fileio.c 138 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540154115421543154415451546154715481549155015511552155315541555155615571558155915601561156215631564156515661567156815691570157115721573157415751576157715781579158015811582158315841585158615871588158915901591159215931594159515961597159815991600160116021603160416051606160716081609161016111612161316141615161616171618161916201621162216231624162516261627162816291630163116321633163416351636163716381639164016411642164316441645164616471648164916501651165216531654165516561657165816591660166116621663166416651666166716681669167016711672167316741675167616771678167916801681168216831684168516861687168816891690169116921693169416951696169716981699170017011702170317041705170617071708170917101711171217131714171517161717171817191720172117221723172417251726172717281729173017311732173317341735173617371738173917401741174217431744174517461747174817491750175117521753175417551756175717581759176017611762176317641765176617671768176917701771177217731774177517761777177817791780178117821783178417851786178717881789179017911792179317941795179617971798179918001801180218031804180518061807180818091810181118121813181418151816181718181819182018211822182318241825182618271828182918301831183218331834183518361837183818391840184118421843184418451846184718481849185018511852185318541855185618571858185918601861186218631864186518661867186818691870187118721873187418751876187718781879188018811882188318841885188618871888188918901891189218931894189518961897189818991900190119021903190419051906190719081909191019111912191319141915191619171918191919201921192219231924192519261927192819291930193119321933193419351936193719381939194019411942194319441945194619471948194919501951195219531954195519561957195819591960196119621963196419651966196719681969197019711972197319741975197619771978197919801981198219831984198519861987198819891990199119921993199419951996199719981999200020012002200320042005200620072008200920102011201220132014201520162017201820192020202120222023202420252026202720282029203020312032203320342035203620372038203920402041204220432044204520462047204820492050205120522053205420552056205720582059206020612062206320642065206620672068206920702071207220732074207520762077207820792080208120822083208420852086208720882089209020912092209320942095209620972098209921002101210221032104210521062107210821092110211121122113211421152116211721182119212021212122212321242125212621272128212921302131213221332134213521362137213821392140214121422143214421452146214721482149215021512152215321542155215621572158215921602161216221632164216521662167216821692170217121722173217421752176217721782179218021812182218321842185218621872188218921902191219221932194219521962197219821992200220122022203220422052206220722082209221022112212221322142215221622172218221922202221222222232224222522262227222822292230223122322233223422352236223722382239224022412242224322442245224622472248224922502251225222532254225522562257225822592260226122622263226422652266226722682269227022712272227322742275227622772278227922802281228222832284228522862287228822892290229122922293229422952296229722982299230023012302230323042305230623072308230923102311231223132314231523162317231823192320232123222323232423252326232723282329233023312332233323342335233623372338233923402341234223432344234523462347234823492350235123522353235423552356235723582359236023612362236323642365236623672368236923702371237223732374237523762377237823792380238123822383238423852386238723882389239023912392239323942395239623972398239924002401240224032404240524062407240824092410241124122413241424152416241724182419242024212422242324242425242624272428242924302431243224332434243524362437243824392440244124422443244424452446244724482449245024512452245324542455245624572458245924602461246224632464246524662467246824692470247124722473247424752476247724782479248024812482248324842485248624872488248924902491249224932494249524962497249824992500250125022503250425052506250725082509251025112512251325142515251625172518251925202521252225232524252525262527252825292530253125322533253425352536253725382539254025412542254325442545254625472548254925502551255225532554255525562557255825592560256125622563256425652566256725682569257025712572257325742575257625772578257925802581258225832584258525862587258825892590259125922593259425952596259725982599260026012602260326042605260626072608260926102611261226132614261526162617261826192620262126222623262426252626262726282629263026312632263326342635263626372638263926402641264226432644264526462647264826492650265126522653265426552656265726582659266026612662266326642665266626672668266926702671267226732674267526762677267826792680268126822683268426852686268726882689269026912692269326942695269626972698269927002701270227032704270527062707270827092710271127122713271427152716271727182719272027212722272327242725272627272728272927302731273227332734273527362737273827392740274127422743274427452746274727482749275027512752275327542755275627572758275927602761276227632764276527662767276827692770277127722773277427752776277727782779278027812782278327842785278627872788278927902791279227932794279527962797279827992800280128022803280428052806280728082809281028112812281328142815281628172818281928202821282228232824282528262827282828292830283128322833283428352836283728382839284028412842284328442845284628472848284928502851285228532854285528562857285828592860286128622863286428652866286728682869287028712872287328742875287628772878287928802881288228832884288528862887288828892890289128922893289428952896289728982899290029012902290329042905290629072908290929102911291229132914291529162917291829192920292129222923292429252926292729282929293029312932293329342935293629372938293929402941294229432944294529462947294829492950295129522953295429552956295729582959296029612962296329642965296629672968296929702971297229732974297529762977297829792980298129822983298429852986298729882989299029912992299329942995299629972998299930003001300230033004300530063007300830093010301130123013301430153016301730183019302030213022302330243025302630273028302930303031303230333034303530363037303830393040304130423043304430453046304730483049305030513052305330543055305630573058305930603061306230633064306530663067306830693070307130723073307430753076307730783079308030813082308330843085308630873088308930903091309230933094309530963097309830993100310131023103310431053106310731083109311031113112311331143115311631173118311931203121312231233124312531263127312831293130313131323133313431353136313731383139314031413142314331443145314631473148314931503151315231533154315531563157315831593160316131623163316431653166316731683169317031713172317331743175317631773178317931803181318231833184318531863187318831893190319131923193319431953196319731983199320032013202320332043205320632073208320932103211321232133214321532163217321832193220322132223223322432253226322732283229323032313232323332343235323632373238323932403241324232433244324532463247324832493250325132523253325432553256325732583259326032613262326332643265326632673268326932703271327232733274327532763277327832793280328132823283328432853286328732883289329032913292329332943295329632973298329933003301330233033304330533063307330833093310331133123313331433153316331733183319332033213322332333243325332633273328332933303331333233333334333533363337333833393340334133423343334433453346334733483349335033513352335333543355335633573358335933603361336233633364336533663367336833693370337133723373337433753376337733783379338033813382338333843385338633873388338933903391339233933394339533963397339833993400340134023403340434053406340734083409341034113412341334143415341634173418341934203421342234233424342534263427342834293430343134323433343434353436343734383439344034413442344334443445344634473448344934503451345234533454345534563457345834593460346134623463346434653466346734683469347034713472347334743475347634773478347934803481348234833484348534863487348834893490349134923493349434953496349734983499350035013502350335043505350635073508350935103511351235133514351535163517351835193520352135223523352435253526352735283529353035313532353335343535353635373538353935403541354235433544354535463547354835493550355135523553355435553556355735583559356035613562356335643565356635673568356935703571357235733574357535763577357835793580358135823583358435853586358735883589359035913592359335943595359635973598359936003601360236033604360536063607360836093610361136123613361436153616361736183619362036213622362336243625362636273628362936303631363236333634363536363637363836393640364136423643364436453646364736483649365036513652365336543655365636573658365936603661366236633664366536663667366836693670367136723673367436753676367736783679368036813682368336843685368636873688368936903691369236933694369536963697369836993700370137023703370437053706370737083709371037113712371337143715371637173718371937203721372237233724372537263727372837293730373137323733373437353736373737383739374037413742374337443745374637473748374937503751375237533754375537563757375837593760376137623763376437653766376737683769377037713772377337743775377637773778377937803781378237833784378537863787378837893790379137923793379437953796379737983799380038013802380338043805380638073808380938103811381238133814381538163817381838193820382138223823382438253826382738283829383038313832383338343835383638373838383938403841384238433844384538463847384838493850385138523853385438553856385738583859386038613862386338643865386638673868386938703871387238733874387538763877387838793880388138823883388438853886388738883889389038913892389338943895389638973898389939003901390239033904390539063907390839093910391139123913391439153916391739183919392039213922392339243925392639273928392939303931393239333934393539363937393839393940394139423943394439453946394739483949395039513952395339543955395639573958395939603961396239633964396539663967396839693970397139723973397439753976397739783979398039813982398339843985398639873988398939903991399239933994399539963997399839994000400140024003400440054006400740084009401040114012401340144015401640174018401940204021402240234024402540264027402840294030403140324033403440354036403740384039404040414042404340444045404640474048404940504051405240534054405540564057405840594060406140624063406440654066406740684069407040714072407340744075407640774078407940804081408240834084408540864087408840894090409140924093409440954096409740984099410041014102410341044105410641074108410941104111411241134114411541164117411841194120412141224123412441254126412741284129413041314132413341344135413641374138413941404141414241434144414541464147414841494150415141524153415441554156415741584159416041614162416341644165416641674168416941704171417241734174417541764177417841794180418141824183418441854186418741884189419041914192419341944195419641974198419942004201420242034204420542064207420842094210421142124213421442154216421742184219422042214222422342244225422642274228422942304231423242334234423542364237423842394240424142424243424442454246424742484249425042514252425342544255425642574258425942604261426242634264426542664267426842694270427142724273427442754276427742784279428042814282428342844285428642874288428942904291429242934294429542964297429842994300430143024303430443054306430743084309431043114312431343144315431643174318431943204321432243234324432543264327432843294330433143324333433443354336433743384339434043414342434343444345434643474348434943504351435243534354435543564357435843594360436143624363436443654366436743684369437043714372437343744375437643774378437943804381438243834384438543864387438843894390439143924393439443954396439743984399440044014402440344044405440644074408440944104411441244134414441544164417441844194420442144224423442444254426442744284429443044314432443344344435443644374438443944404441444244434444444544464447444844494450445144524453445444554456445744584459446044614462446344644465446644674468446944704471447244734474447544764477447844794480448144824483448444854486448744884489449044914492449344944495449644974498449945004501450245034504450545064507450845094510451145124513451445154516451745184519452045214522452345244525452645274528452945304531453245334534453545364537453845394540454145424543454445454546454745484549455045514552455345544555455645574558455945604561456245634564456545664567456845694570457145724573457445754576457745784579458045814582458345844585458645874588458945904591459245934594459545964597459845994600460146024603460446054606460746084609461046114612461346144615461646174618461946204621462246234624462546264627462846294630463146324633463446354636463746384639464046414642464346444645464646474648464946504651465246534654465546564657465846594660466146624663466446654666466746684669467046714672467346744675467646774678467946804681468246834684468546864687468846894690469146924693469446954696469746984699470047014702470347044705470647074708470947104711471247134714471547164717471847194720472147224723472447254726472747284729473047314732473347344735473647374738473947404741474247434744474547464747474847494750475147524753475447554756475747584759476047614762476347644765476647674768476947704771477247734774477547764777477847794780478147824783478447854786478747884789479047914792479347944795479647974798479948004801480248034804480548064807480848094810481148124813481448154816481748184819482048214822482348244825482648274828482948304831483248334834483548364837483848394840484148424843484448454846484748484849485048514852485348544855485648574858485948604861486248634864486548664867486848694870487148724873487448754876487748784879488048814882488348844885488648874888488948904891489248934894489548964897489848994900490149024903
  1. /*
  2. fileio.c - Zip 3
  3. Copyright (c) 1990-2008 Info-ZIP. All rights reserved.
  4. See the accompanying file LICENSE, version 2007-Mar-4 or later
  5. (the contents of which are also included in zip.h) for terms of use.
  6. If, for some reason, all these files are missing, the Info-ZIP license
  7. also may be found at: ftp://ftp.info-zip.org/pub/infozip/license.html
  8. */
  9. /*
  10. * fileio.c by Mark Adler
  11. */
  12. #define __FILEIO_C
  13. #include "zip.h"
  14. #include "crc32.h"
  15. #ifdef MACOS
  16. # include "helpers.h"
  17. #endif
  18. #ifdef VMS
  19. # include "vms/vms.h"
  20. #endif /* def VMS */
  21. #include <time.h>
  22. #ifdef NO_MKTIME
  23. time_t mktime OF((struct tm *));
  24. #endif
  25. #ifdef OSF
  26. #define EXDEV 18 /* avoid a bug in the DEC OSF/1 header files. */
  27. #else
  28. #include <errno.h>
  29. #endif
  30. #ifdef NO_ERRNO
  31. extern int errno;
  32. #endif
  33. /* -----------------------
  34. For long option support
  35. ----------------------- */
  36. #include <ctype.h>
  37. #if defined(VMS) || defined(TOPS20)
  38. # define PAD 5
  39. #else
  40. # define PAD 0
  41. #endif
  42. #ifdef NO_RENAME
  43. int rename OF((ZCONST char *, ZCONST char *));
  44. #endif
  45. /* Local functions */
  46. local int optionerr OF((char *, ZCONST char *, int, int));
  47. local unsigned long get_shortopt OF((char **, int, int *, int *, char **, int *, int));
  48. local unsigned long get_longopt OF((char **, int, int *, int *, char **, int *, int));
  49. #ifdef UNICODE_SUPPORT
  50. local int utf8_char_bytes OF((ZCONST char *utf8));
  51. local long ucs4_char_from_utf8 OF((ZCONST char **utf8 ));
  52. local int utf8_from_ucs4_char OF((char *utf8buf, ulg ch));
  53. local int utf8_to_ucs4_string OF((ZCONST char *utf8, ulg *usc4buf,
  54. int buflen));
  55. local int ucs4_string_to_utf8 OF((ZCONST ulg *ucs4, char *utf8buf,
  56. int buflen));
  57. #if 0
  58. local int utf8_chars OF((ZCONST char *utf8));
  59. #endif
  60. #endif /* UNICODE_SUPPORT */
  61. #ifndef UTIL /* the companion #endif is a bit of ways down ... */
  62. local int fqcmp OF((ZCONST zvoid *, ZCONST zvoid *));
  63. local int fqcmpz OF((ZCONST zvoid *, ZCONST zvoid *));
  64. /* Local module level variables. */
  65. char *label = NULL; /* global, but only used in `system'.c */
  66. local z_stat zipstatb; /* now use z_stat globally - 7/24/04 EG */
  67. #if defined(UNICODE_SUPPORT) && defined(WIN32)
  68. local zw_stat zipstatbw;
  69. #endif
  70. #if (!defined(MACOS) && !defined(WINDLL))
  71. local int zipstate = -1;
  72. #else
  73. int zipstate;
  74. #endif
  75. /* -1 unknown, 0 old zip file exists, 1 new zip file */
  76. #if 0
  77. char *getnam(n, fp)
  78. char *n; /* where to put name (must have >=FNMAX+1 bytes) */
  79. #endif
  80. /* converted to return string pointer from malloc to avoid
  81. size limitation - 11/8/04 EG */
  82. #define GETNAM_MAX 9000 /* hopefully big enough for now */
  83. char *getnam(fp)
  84. FILE *fp;
  85. /* Read a \n or \r delimited name from stdin into n, and return
  86. n. If EOF, then return NULL. Also, if problem return NULL. */
  87. {
  88. char name[GETNAM_MAX + 1];
  89. int c; /* last character read */
  90. char *p; /* pointer into name area */
  91. p = name;
  92. while ((c = getc(fp)) == '\n' || c == '\r')
  93. ;
  94. if (c == EOF)
  95. return NULL;
  96. do {
  97. if (p - name >= GETNAM_MAX)
  98. return NULL;
  99. *p++ = (char) c;
  100. c = getc(fp);
  101. } while (c != EOF && (c != '\n' && c != '\r'));
  102. #ifdef WIN32
  103. /*
  104. * WIN32 strips off trailing spaces and periods in filenames
  105. * XXX what about a filename that only consists of spaces ?
  106. * Answer: on WIN32, a filename must contain at least one non-space char
  107. */
  108. while (p > name) {
  109. if ((c = p[-1]) != ' ' && c != '.')
  110. break;
  111. --p;
  112. }
  113. #endif
  114. *p = 0;
  115. /* malloc a copy */
  116. if ((p = malloc(strlen(name) + 1)) == NULL) {
  117. return NULL;
  118. }
  119. strcpy(p, name);
  120. return p;
  121. }
  122. struct flist far *fexpel(f)
  123. struct flist far *f; /* entry to delete */
  124. /* Delete the entry *f in the doubly-linked found list. Return pointer to
  125. next entry to allow stepping through list. */
  126. {
  127. struct flist far *t; /* temporary variable */
  128. t = f->nxt;
  129. *(f->lst) = t; /* point last to next, */
  130. if (t != NULL)
  131. t->lst = f->lst; /* and next to last */
  132. if (f->name != NULL) /* free memory used */
  133. free((zvoid *)(f->name));
  134. if (f->zname != NULL)
  135. free((zvoid *)(f->zname));
  136. if (f->iname != NULL)
  137. free((zvoid *)(f->iname));
  138. #ifdef UNICODE_SUPPORT
  139. if (f->uname)
  140. free((zvoid *)f->uname);
  141. # ifdef WIN32
  142. if (f->namew)
  143. free((zvoid *)f->namew);
  144. if (f->inamew)
  145. free((zvoid *)f->inamew);
  146. if (f->znamew)
  147. free((zvoid *)f->znamew);
  148. # endif
  149. #endif
  150. farfree((zvoid far *)f);
  151. fcount--; /* decrement count */
  152. return t; /* return pointer to next */
  153. }
  154. local int fqcmp(a, b)
  155. ZCONST zvoid *a, *b; /* pointers to pointers to found entries */
  156. /* Used by qsort() to compare entries in the found list by name. */
  157. {
  158. return strcmp((*(struct flist far **)a)->name,
  159. (*(struct flist far **)b)->name);
  160. }
  161. local int fqcmpz(a, b)
  162. ZCONST zvoid *a, *b; /* pointers to pointers to found entries */
  163. /* Used by qsort() to compare entries in the found list by iname. */
  164. {
  165. return strcmp((*(struct flist far **)a)->iname,
  166. (*(struct flist far **)b)->iname);
  167. }
  168. char *last(p, c)
  169. char *p; /* sequence of path components */
  170. int c; /* path components separator character */
  171. /* Return a pointer to the start of the last path component. For a directory
  172. * name terminated by the character in c, the return value is an empty string.
  173. */
  174. {
  175. char *t; /* temporary variable */
  176. if ((t = strrchr(p, c)) != NULL)
  177. return t + 1;
  178. else
  179. #ifndef AOS_VS
  180. return p;
  181. #else
  182. /* We want to allow finding of end of path in either AOS/VS-style pathnames
  183. * or Unix-style pathnames. This presents a few little problems ...
  184. */
  185. {
  186. if (*p == '=' || *p == '^') /* like ./ and ../ respectively */
  187. return p + 1;
  188. else
  189. return p;
  190. }
  191. #endif
  192. }
  193. #if defined(UNICODE_SUPPORT) && defined(WIN32)
  194. wchar_t *lastw(pw, c)
  195. wchar_t *pw; /* sequence of path components */
  196. wchar_t c; /* path components separator character */
  197. /* Return a pointer to the start of the last path component. For a directory
  198. * name terminated by the character in c, the return value is an empty string.
  199. */
  200. {
  201. wchar_t *tw; /* temporary variable */
  202. if ((tw = wcsrchr(pw, c)) != NULL)
  203. return tw + 1;
  204. else
  205. # ifndef AOS_VS
  206. return pw;
  207. # else
  208. /* We want to allow finding of end of path in either AOS/VS-style pathnames
  209. * or Unix-style pathnames. This presents a few little problems ...
  210. */
  211. {
  212. if (*pw == (wchar_t)'=' || *pw == (wchar_t)'^') /* like ./ and ../ respectively */
  213. return pw + 1;
  214. else
  215. return pw;
  216. }
  217. # endif
  218. }
  219. #endif
  220. char *msname(n)
  221. char *n;
  222. /* Reduce all path components to MSDOS upper case 8.3 style names. */
  223. {
  224. int c; /* current character */
  225. int f; /* characters in current component */
  226. char *p; /* source pointer */
  227. char *q; /* destination pointer */
  228. p = q = n;
  229. f = 0;
  230. while ((c = (unsigned char)*POSTINCSTR(p)) != 0)
  231. if (c == ' ' || c == ':' || c == '"' || c == '*' || c == '+' ||
  232. c == ',' || c == ';' || c == '<' || c == '=' || c == '>' ||
  233. c == '?' || c == '[' || c == ']' || c == '|')
  234. continue; /* char is discarded */
  235. else if (c == '/')
  236. {
  237. *POSTINCSTR(q) = (char)c;
  238. f = 0; /* new component */
  239. }
  240. #ifdef __human68k__
  241. else if (ismbblead(c) && *p)
  242. {
  243. if (f == 7 || f == 11)
  244. f++;
  245. else if (*p && f < 12 && f != 8)
  246. {
  247. *q++ = c;
  248. *q++ = *p++;
  249. f += 2;
  250. }
  251. }
  252. #endif /* __human68k__ */
  253. else if (c == '.')
  254. {
  255. if (f == 0)
  256. continue; /* leading dots are discarded */
  257. else if (f < 9)
  258. {
  259. *POSTINCSTR(q) = (char)c;
  260. f = 9; /* now in file type */
  261. }
  262. else
  263. f = 12; /* now just excess characters */
  264. }
  265. else
  266. if (f < 12 && f != 8)
  267. {
  268. f += CLEN(p); /* do until end of name or type */
  269. *POSTINCSTR(q) = (char)(to_up(c));
  270. }
  271. *q = 0;
  272. return n;
  273. }
  274. #ifdef UNICODE_SUPPORT
  275. wchar_t *msnamew(nw)
  276. wchar_t *nw;
  277. /* Reduce all path components to MSDOS upper case 8.3 style names. */
  278. {
  279. wchar_t c; /* current character */
  280. int f; /* characters in current component */
  281. wchar_t *pw; /* source pointer */
  282. wchar_t *qw; /* destination pointer */
  283. pw = qw = nw;
  284. f = 0;
  285. while ((c = (unsigned char)*pw++) != 0)
  286. if (c == ' ' || c == ':' || c == '"' || c == '*' || c == '+' ||
  287. c == ',' || c == ';' || c == '<' || c == '=' || c == '>' ||
  288. c == '?' || c == '[' || c == ']' || c == '|')
  289. continue; /* char is discarded */
  290. else if (c == '/')
  291. {
  292. *qw++ = c;
  293. f = 0; /* new component */
  294. }
  295. #ifdef __human68k__
  296. else if (ismbblead(c) && *pw)
  297. {
  298. if (f == 7 || f == 11)
  299. f++;
  300. else if (*pw && f < 12 && f != 8)
  301. {
  302. *qw++ = c;
  303. *qw++ = *pw++;
  304. f += 2;
  305. }
  306. }
  307. #endif /* __human68k__ */
  308. else if (c == '.')
  309. {
  310. if (f == 0)
  311. continue; /* leading dots are discarded */
  312. else if (f < 9)
  313. {
  314. *qw++ = c;
  315. f = 9; /* now in file type */
  316. }
  317. else
  318. f = 12; /* now just excess characters */
  319. }
  320. else
  321. if (f < 12 && f != 8)
  322. {
  323. f++; /* do until end of name or type */
  324. *qw++ = towupper(c);
  325. }
  326. *qw = 0;
  327. return nw;
  328. }
  329. #endif
  330. int proc_archive_name(n, caseflag)
  331. char *n; /* name to process */
  332. int caseflag; /* true to force case-sensitive match */
  333. /* Process a name or sh expression in existing archive to operate
  334. on (or exclude). Return an error code in the ZE_ class. */
  335. {
  336. int m; /* matched flag */
  337. char *p; /* path for recursion */
  338. struct zlist far *z; /* steps through zfiles list */
  339. if (strcmp(n, "-") == 0) { /* if compressing stdin */
  340. zipwarn("Cannot select stdin when selecting archive entries", "");
  341. return ZE_MISS;
  342. }
  343. else
  344. {
  345. /* Search for shell expression in zip file */
  346. p = ex2in(n, 0, (int *)NULL); /* shouldn't affect matching chars */
  347. m = 1;
  348. for (z = zfiles; z != NULL; z = z->nxt) {
  349. if (MATCH(p, z->iname, caseflag))
  350. {
  351. z->mark = pcount ? filter(z->zname, caseflag) : 1;
  352. if (verbose)
  353. fprintf(mesg, "zip diagnostic: %scluding %s\n",
  354. z->mark ? "in" : "ex", z->oname);
  355. m = 0;
  356. }
  357. }
  358. #ifdef UNICODE_SUPPORT
  359. /* also check escaped Unicode names */
  360. for (z = zfiles; z != NULL; z = z->nxt) {
  361. if (z->zuname) {
  362. #ifdef WIN32
  363. /* It seems something is lost in going from a listed
  364. name from zip -su in a console window to using that
  365. name in a command line. This kluge may fix it
  366. and just takes zuname, converts to oem (i.e. ouname),
  367. then converts it back which ends up not the same as
  368. started with.
  369. */
  370. char *zuname = z->wuname;
  371. #else
  372. char *zuname = z->zuname;
  373. #endif
  374. if (MATCH(p, zuname, caseflag))
  375. {
  376. z->mark = pcount ? filter(zuname, caseflag) : 1;
  377. if (verbose) {
  378. fprintf(mesg, "zip diagnostic: %scluding %s\n",
  379. z->mark ? "in" : "ex", z->oname);
  380. fprintf(mesg, " Escaped Unicode: %s\n",
  381. z->ouname);
  382. }
  383. m = 0;
  384. }
  385. }
  386. }
  387. #endif
  388. free((zvoid *)p);
  389. return m ? ZE_MISS : ZE_OK;
  390. }
  391. }
  392. int check_dup()
  393. /* Sort the found list and remove duplicates.
  394. Return an error code in the ZE_ class. */
  395. {
  396. struct flist far *f; /* steps through found linked list */
  397. extent j, k; /* indices for s */
  398. struct flist far **s; /* sorted table */
  399. struct flist far **nodup; /* sorted table without duplicates */
  400. /* sort found list, remove duplicates */
  401. if (fcount)
  402. {
  403. extent fl_size = fcount * sizeof(struct flist far *);
  404. if ((fl_size / sizeof(struct flist far *)) != fcount ||
  405. (s = (struct flist far **)malloc(fl_size)) == NULL)
  406. return ZE_MEM;
  407. for (j = 0, f = found; f != NULL; f = f->nxt)
  408. s[j++] = f;
  409. /* Check names as given (f->name) */
  410. qsort((char *)s, fcount, sizeof(struct flist far *), fqcmp);
  411. for (k = j = fcount - 1; j > 0; j--)
  412. if (strcmp(s[j - 1]->name, s[j]->name) == 0)
  413. /* remove duplicate entry from list */
  414. fexpel(s[j]); /* fexpel() changes fcount */
  415. else
  416. /* copy valid entry into destination position */
  417. s[k--] = s[j];
  418. s[k] = s[0]; /* First entry is always valid */
  419. nodup = &s[k]; /* Valid entries are at end of array s */
  420. /* sort only valid items and check for unique internal names (f->iname) */
  421. qsort((char *)nodup, fcount, sizeof(struct flist far *), fqcmpz);
  422. for (j = 1; j < fcount; j++)
  423. if (strcmp(nodup[j - 1]->iname, nodup[j]->iname) == 0)
  424. {
  425. char tempbuf[FNMAX+4081];
  426. sprintf(errbuf, " first full name: %s\n", nodup[j - 1]->name);
  427. sprintf(tempbuf, " second full name: %s\n", nodup[j]->name);
  428. strcat(errbuf, " ");
  429. strcat(errbuf, tempbuf);
  430. #ifdef EBCDIC
  431. strtoebc(nodup[j]->iname, nodup[j]->iname);
  432. #endif
  433. sprintf(tempbuf, "name in zip file repeated: %s", nodup[j]->iname);
  434. strcat(errbuf, " ");
  435. strcat(errbuf, tempbuf);
  436. if (pathput == 0) {
  437. strcat(errbuf, "\n this may be a result of using -j");
  438. }
  439. #ifdef EBCDIC
  440. strtoasc(nodup[j]->iname, nodup[j]->iname);
  441. #endif
  442. zipwarn(errbuf, "");
  443. return ZE_PARMS;
  444. }
  445. free((zvoid *)s);
  446. }
  447. return ZE_OK;
  448. }
  449. int filter(name, casesensitive)
  450. char *name;
  451. int casesensitive;
  452. /* Scan the -R, -i and -x lists for matches to the given name.
  453. Return TRUE if the name must be included, FALSE otherwise.
  454. Give precedence to -x over -i and -R.
  455. Note that if both R and i patterns are given then must
  456. have a match for both.
  457. This routine relies on the following global variables:
  458. patterns array of match pattern structures
  459. pcount total number of patterns
  460. icount number of -i patterns
  461. Rcount number of -R patterns
  462. These data are set up by the command line parsing code.
  463. */
  464. {
  465. unsigned int n;
  466. int slashes;
  467. char *p, *q;
  468. /* without -i patterns, every name matches the "-i select rules" */
  469. int imatch = (icount == 0);
  470. /* without -R patterns, every name matches the "-R select rules" */
  471. int Rmatch = (Rcount == 0);
  472. if (pcount == 0) return TRUE;
  473. for (n = 0; n < pcount; n++) {
  474. if (!patterns[n].zname[0]) /* it can happen... */
  475. continue;
  476. p = name;
  477. switch (patterns[n].select) {
  478. case 'R':
  479. if (Rmatch)
  480. /* one -R match is sufficient, skip this pattern */
  481. continue;
  482. /* With -R patterns, if the pattern has N path components (that is,
  483. N-1 slashes), then we test only the last N components of name.
  484. */
  485. slashes = 0;
  486. for (q = patterns[n].zname; (q = MBSCHR(q, '/')) != NULL; MB_NEXTCHAR(q))
  487. slashes++;
  488. /* The name may have M path components (M-1 slashes) */
  489. for (q = p; (q = MBSCHR(q, '/')) != NULL; MB_NEXTCHAR(q))
  490. slashes--;
  491. /* Now, "slashes" contains the difference "N-M" between the number
  492. of path components in the pattern (N) and in the name (M).
  493. */
  494. if (slashes < 0)
  495. /* We found "M > N"
  496. --> skip the first (M-N) path components of the name.
  497. */
  498. for (q = p; (q = MBSCHR(q, '/')) != NULL; MB_NEXTCHAR(q))
  499. if (++slashes == 0) {
  500. p = q + 1; /* q points at '/', mblen("/") is 1 */
  501. break;
  502. }
  503. break;
  504. case 'i':
  505. if (imatch)
  506. /* one -i match is sufficient, skip this pattern */
  507. continue;
  508. break;
  509. }
  510. if (MATCH(patterns[n].zname, p, casesensitive)) {
  511. switch (patterns[n].select) {
  512. case 'x':
  513. /* The -x match takes precedence over everything else */
  514. return FALSE;
  515. case 'R':
  516. Rmatch = TRUE;
  517. break;
  518. default:
  519. /* this must be a type -i match */
  520. imatch = TRUE;
  521. break;
  522. }
  523. }
  524. }
  525. return imatch && Rmatch;
  526. }
  527. #ifdef UNICODE_SUPPORT
  528. # ifdef WIN32
  529. int newnamew(namew, isdir, casesensitive)
  530. wchar_t *namew; /* name to add (or exclude) */
  531. int isdir; /* true for a directory */
  532. int casesensitive; /* true for case-sensitive matching */
  533. /* Add (or exclude) the name of an existing disk file. Return an error
  534. code in the ZE_ class. */
  535. {
  536. wchar_t *inamew = NULL; /* internal name */
  537. wchar_t *znamew = NULL; /* external version of iname */
  538. wchar_t *undosmw = NULL; /* zname version with "-j" and "-k" options disabled */
  539. char *oname = NULL; /* iname converted for display */
  540. char *name = NULL;
  541. char *iname = NULL;
  542. char *zname = NULL;
  543. char *zuname = NULL;
  544. char *undosm = NULL;
  545. struct flist far *f; /* where in found, or new found entry */
  546. struct zlist far *z; /* where in zfiles (if found) */
  547. int dosflag;
  548. /* Scanning files ...
  549. *
  550. * After 5 seconds output Scanning files...
  551. * then a dot every 2 seconds
  552. */
  553. if (noisy) {
  554. /* If find files then output message after delay */
  555. if (scan_count == 0) {
  556. time_t current = time(NULL);
  557. scan_start = current;
  558. }
  559. scan_count++;
  560. if (scan_count % 100 == 0) {
  561. time_t current = time(NULL);
  562. if (current - scan_start > scan_delay) {
  563. if (scan_last == 0) {
  564. zipmessage_nl("Scanning files ", 0);
  565. scan_last = current;
  566. }
  567. if (current - scan_last > scan_dot_time) {
  568. scan_last = current;
  569. fprintf(mesg, ".");
  570. fflush(mesg);
  571. }
  572. }
  573. }
  574. }
  575. /* Search for name in zip file. If there, mark it, else add to
  576. list of new names to do (or remove from that list). */
  577. if ((inamew = ex2inw(namew, isdir, &dosflag)) == NULL)
  578. return ZE_MEM;
  579. /* Discard directory names with zip -rj */
  580. if (*inamew == (wchar_t)'\0') {
  581. /* If extensions needs to be swapped, we will have empty directory names
  582. instead of the original directory. For example, zipping 'c.', 'c.main'
  583. should zip only 'main.c' while 'c.' will be converted to '\0' by ex2in. */
  584. if (pathput && !recurse) error("empty name without -j or -r");
  585. free((zvoid *)inamew);
  586. return ZE_OK;
  587. }
  588. if (dosflag || !pathput) {
  589. int save_dosify = dosify, save_pathput = pathput;
  590. dosify = 0;
  591. pathput = 1;
  592. /* zname is temporarly mis-used as "undosmode" iname pointer */
  593. if ((znamew = ex2inw(namew, isdir, NULL)) != NULL) {
  594. undosmw = in2exw(znamew);
  595. free(znamew);
  596. }
  597. dosify = save_dosify;
  598. pathput = save_pathput;
  599. }
  600. if ((znamew = in2exw(inamew)) == NULL)
  601. return ZE_MEM;
  602. /* Convert names from wchar_t to char */
  603. name = wchar_to_local_string(namew);
  604. iname = wchar_to_local_string(inamew);
  605. zname = wchar_to_local_string(znamew);
  606. oname = local_to_display_string(zname);
  607. zuname = wchar_to_local_string(znamew);
  608. if (undosmw == NULL)
  609. undosmw = znamew;
  610. undosm = wchar_to_local_string(undosmw);
  611. if ((z = zsearch(zuname)) != NULL) {
  612. if (pcount && !filter(undosm, casesensitive)) {
  613. /* Do not clear z->mark if "exclude", because, when "dosify || !pathput"
  614. * is in effect, two files with different filter options may hit the
  615. * same z entry.
  616. */
  617. if (verbose)
  618. fprintf(mesg, "excluding %s\n", oname);
  619. } else {
  620. z->mark = 1;
  621. if ((z->name = malloc(strlen(name) + 1 + PAD)) == NULL) {
  622. if (undosmw != znamew)
  623. free(undosmw);
  624. if (undosm) free(undosm);
  625. if (inamew) free(inamew);
  626. if (znamew) free(znamew);
  627. if (name) free(name);
  628. if (iname) free(iname);
  629. if (zname) free(zname);
  630. if (oname) free(oname);
  631. if (zuname) free(zuname);
  632. return ZE_MEM;
  633. }
  634. strcpy(z->name, name);
  635. z->oname = oname;
  636. oname = NULL;
  637. z->dosflag = dosflag;
  638. #ifdef FORCE_NEWNAME
  639. free((zvoid *)(z->iname));
  640. z->iname = iname;
  641. iname = NULL;
  642. #else
  643. /* Better keep the old name. Useful when updating on MSDOS a zip file
  644. * made on Unix.
  645. */
  646. #endif /* ? FORCE_NEWNAME */
  647. }
  648. if ((z->namew = (wchar_t *)malloc((wcslen(namew) + 1) * sizeof(wchar_t))) == NULL) {
  649. if (undosmw != znamew)
  650. free(undosmw);
  651. if (undosm) free(undosm);
  652. if (inamew) free(inamew);
  653. if (znamew) free(znamew);
  654. if (name) free(name);
  655. if (iname) free(iname);
  656. if (zname) free(zname);
  657. if (oname) free(oname);
  658. if (zuname) free(zuname);
  659. return ZE_MEM;
  660. }
  661. wcscpy(z->namew, namew);
  662. z->inamew = inamew;
  663. inamew = NULL;
  664. z->znamew = znamew;
  665. znamew = NULL;
  666. z->uname = wchar_to_utf8_string(z->inamew);
  667. if (name == label) {
  668. label = z->name;
  669. }
  670. } else if (pcount == 0 || filter(undosm, casesensitive)) {
  671. /* Check that we are not adding the zip file to itself. This
  672. * catches cases like "zip -m foo ../dir/foo.zip".
  673. */
  674. /* Version of stat() for CMS/MVS isn't complete enough to see if */
  675. /* files match. Just let ZIP.C compare the filenames. That's good */
  676. /* enough for CMS anyway since there aren't paths to worry about. */
  677. zw_stat statbw; /* need for wide stat */
  678. wchar_t *zipfilew = local_to_wchar_string(zipfile);
  679. if (zipstate == -1)
  680. zipstate = strcmp(zipfile, "-") != 0 &&
  681. zwstat(zipfilew, &zipstatbw) == 0;
  682. free(zipfilew);
  683. if (zipstate == 1 && (statbw = zipstatbw, zwstat(namew, &statbw) == 0
  684. && zipstatbw.st_mode == statbw.st_mode
  685. && zipstatbw.st_ino == statbw.st_ino
  686. && zipstatbw.st_dev == statbw.st_dev
  687. && zipstatbw.st_uid == statbw.st_uid
  688. && zipstatbw.st_gid == statbw.st_gid
  689. && zipstatbw.st_size == statbw.st_size
  690. && zipstatbw.st_mtime == statbw.st_mtime
  691. && zipstatbw.st_ctime == statbw.st_ctime)) {
  692. /* Don't compare a_time since we are reading the file */
  693. if (verbose)
  694. fprintf(mesg, "file matches zip file -- skipping\n");
  695. if (undosmw != znamew)
  696. free(undosmw);
  697. if (undosm) free(undosm);
  698. if (inamew) free(inamew);
  699. if (znamew) free(znamew);
  700. if (name) free(name);
  701. if (iname) free(iname);
  702. if (zname) free(zname);
  703. if (oname) free(oname);
  704. if (zuname) free(zuname);
  705. return ZE_OK;
  706. }
  707. /* allocate space and add to list */
  708. if ((f = (struct flist far *)farmalloc(sizeof(struct flist))) == NULL ||
  709. fcount + 1 < fcount ||
  710. (f->name = malloc(strlen(name) + 1 + PAD)) == NULL)
  711. {
  712. if (f != NULL)
  713. farfree((zvoid far *)f);
  714. if (undosmw != znamew)
  715. free(undosmw);
  716. if (undosm) free(undosm);
  717. if (inamew) free(inamew);
  718. if (znamew) free(znamew);
  719. if (name) free(name);
  720. if (iname) free(iname);
  721. if (zname) free(zname);
  722. if (oname) free(oname);
  723. if (zuname) free(zuname);
  724. return ZE_MEM;
  725. }
  726. if (undosmw != znamew)
  727. free((zvoid *)undosmw);
  728. strcpy(f->name, name);
  729. f->iname = iname;
  730. iname = NULL;
  731. f->zname = zname;
  732. zname = NULL;
  733. /* Unicode */
  734. if ((f->namew = (wchar_t *)malloc((wcslen(namew) + 1) * sizeof(wchar_t))) == NULL) {
  735. if (f != NULL)
  736. farfree((zvoid far *)f);
  737. if (undosmw != znamew)
  738. free(undosmw);
  739. if (undosm) free(undosm);
  740. if (inamew) free(inamew);
  741. if (znamew) free(znamew);
  742. if (name) free(name);
  743. if (iname) free(iname);
  744. if (zname) free(zname);
  745. if (oname) free(oname);
  746. if (zuname) free(zuname);
  747. return ZE_MEM;
  748. }
  749. wcscpy(f->namew, namew);
  750. f->znamew = znamew;
  751. znamew = NULL;
  752. f->uname = wchar_to_utf8_string(inamew);
  753. f->inamew = inamew;
  754. inamew = NULL;
  755. f->oname = oname;
  756. oname = NULL;
  757. f->dosflag = dosflag;
  758. *fnxt = f;
  759. f->lst = fnxt;
  760. f->nxt = NULL;
  761. fnxt = &f->nxt;
  762. fcount++;
  763. if (name == label) {
  764. label = f->name;
  765. }
  766. }
  767. if (undosm) free(undosm);
  768. if (inamew) free(inamew);
  769. if (znamew) free(znamew);
  770. if (name) free(name);
  771. if (iname) free(iname);
  772. if (zname) free(zname);
  773. if (oname) free(oname);
  774. if (zuname) free(zuname);
  775. return ZE_OK;
  776. }
  777. # endif
  778. #endif
  779. int newname(name, isdir, casesensitive)
  780. char *name; /* name to add (or exclude) */
  781. int isdir; /* true for a directory */
  782. int casesensitive; /* true for case-sensitive matching */
  783. /* Add (or exclude) the name of an existing disk file. Return an error
  784. code in the ZE_ class. */
  785. {
  786. char *iname, *zname; /* internal name, external version of iname */
  787. char *undosm; /* zname version with "-j" and "-k" options disabled */
  788. char *oname; /* iname converted for display */
  789. struct flist far *f; /* where in found, or new found entry */
  790. struct zlist far *z; /* where in zfiles (if found) */
  791. int dosflag;
  792. /* Scanning files ...
  793. *
  794. * After 5 seconds output Scanning files...
  795. * then a dot every 2 seconds
  796. */
  797. if (noisy) {
  798. /* If find files then output message after delay */
  799. if (scan_count == 0) {
  800. time_t current = time(NULL);
  801. scan_start = current;
  802. }
  803. scan_count++;
  804. if (scan_count % 100 == 0) {
  805. time_t current = time(NULL);
  806. if (current - scan_start > scan_delay) {
  807. if (scan_last == 0) {
  808. zipmessage_nl("Scanning files ", 0);
  809. scan_last = current;
  810. }
  811. if (current - scan_last > scan_dot_time) {
  812. scan_last = current;
  813. fprintf(mesg, ".");
  814. fflush(mesg);
  815. }
  816. }
  817. }
  818. }
  819. /* Search for name in zip file. If there, mark it, else add to
  820. list of new names to do (or remove from that list). */
  821. if ((iname = ex2in(name, isdir, &dosflag)) == NULL)
  822. return ZE_MEM;
  823. /* Discard directory names with zip -rj */
  824. if (*iname == '\0') {
  825. #ifndef AMIGA
  826. /* A null string is a legitimate external directory name in AmigaDOS; also,
  827. * a command like "zip -r zipfile FOO:" produces an empty internal name.
  828. */
  829. # ifndef RISCOS
  830. /* If extensions needs to be swapped, we will have empty directory names
  831. instead of the original directory. For example, zipping 'c.', 'c.main'
  832. should zip only 'main.c' while 'c.' will be converted to '\0' by ex2in. */
  833. if (pathput && !recurse) error("empty name without -j or -r");
  834. # endif /* !RISCOS */
  835. #endif /* !AMIGA */
  836. free((zvoid *)iname);
  837. return ZE_OK;
  838. }
  839. undosm = NULL;
  840. if (dosflag || !pathput) {
  841. int save_dosify = dosify, save_pathput = pathput;
  842. dosify = 0;
  843. pathput = 1;
  844. /* zname is temporarly mis-used as "undosmode" iname pointer */
  845. if ((zname = ex2in(name, isdir, NULL)) != NULL) {
  846. undosm = in2ex(zname);
  847. free(zname);
  848. }
  849. dosify = save_dosify;
  850. pathput = save_pathput;
  851. }
  852. if ((zname = in2ex(iname)) == NULL)
  853. return ZE_MEM;
  854. #ifdef UNICODE_SUPPORT
  855. /* Convert name to display or OEM name */
  856. oname = local_to_display_string(iname);
  857. #else
  858. if ((oname = malloc(strlen(zname) + 1)) == NULL)
  859. return ZE_MEM;
  860. strcpy(oname, zname);
  861. #endif
  862. if (undosm == NULL)
  863. undosm = zname;
  864. if ((z = zsearch(zname)) != NULL) {
  865. if (pcount && !filter(undosm, casesensitive)) {
  866. /* Do not clear z->mark if "exclude", because, when "dosify || !pathput"
  867. * is in effect, two files with different filter options may hit the
  868. * same z entry.
  869. */
  870. if (verbose)
  871. fprintf(mesg, "excluding %s\n", oname);
  872. free((zvoid *)iname);
  873. free((zvoid *)zname);
  874. } else {
  875. z->mark = 1;
  876. if ((z->name = malloc(strlen(name) + 1 + PAD)) == NULL) {
  877. if (undosm != zname)
  878. free((zvoid *)undosm);
  879. free((zvoid *)iname);
  880. free((zvoid *)zname);
  881. return ZE_MEM;
  882. }
  883. strcpy(z->name, name);
  884. z->oname = oname;
  885. z->dosflag = dosflag;
  886. #ifdef FORCE_NEWNAME
  887. free((zvoid *)(z->iname));
  888. z->iname = iname;
  889. #else
  890. /* Better keep the old name. Useful when updating on MSDOS a zip file
  891. * made on Unix.
  892. */
  893. free((zvoid *)iname);
  894. free((zvoid *)zname);
  895. #endif /* ? FORCE_NEWNAME */
  896. }
  897. #if defined(UNICODE_SUPPORT) && defined(WIN32)
  898. z->namew = NULL;
  899. z->inamew = NULL;
  900. z->znamew = NULL;
  901. #endif
  902. if (name == label) {
  903. label = z->name;
  904. }
  905. } else if (pcount == 0 || filter(undosm, casesensitive)) {
  906. /* Check that we are not adding the zip file to itself. This
  907. * catches cases like "zip -m foo ../dir/foo.zip".
  908. */
  909. #ifndef CMS_MVS
  910. /* Version of stat() for CMS/MVS isn't complete enough to see if */
  911. /* files match. Just let ZIP.C compare the filenames. That's good */
  912. /* enough for CMS anyway since there aren't paths to worry about. */
  913. z_stat statb; /* now use structure z_stat and function zstat globally 7/24/04 EG */
  914. if (zipstate == -1)
  915. zipstate = strcmp(zipfile, "-") != 0 &&
  916. zstat(zipfile, &zipstatb) == 0;
  917. if (zipstate == 1 && (statb = zipstatb, zstat(name, &statb) == 0
  918. && zipstatb.st_mode == statb.st_mode
  919. #ifdef VMS
  920. && memcmp(zipstatb.st_ino, statb.st_ino, sizeof(statb.st_ino)) == 0
  921. && strcmp(zipstatb.st_dev, statb.st_dev) == 0
  922. && zipstatb.st_uid == statb.st_uid
  923. #else /* !VMS */
  924. && zipstatb.st_ino == statb.st_ino
  925. && zipstatb.st_dev == statb.st_dev
  926. && zipstatb.st_uid == statb.st_uid
  927. && zipstatb.st_gid == statb.st_gid
  928. #endif /* ?VMS */
  929. && zipstatb.st_size == statb.st_size
  930. && zipstatb.st_mtime == statb.st_mtime
  931. && zipstatb.st_ctime == statb.st_ctime)) {
  932. /* Don't compare a_time since we are reading the file */
  933. if (verbose)
  934. fprintf(mesg, "file matches zip file -- skipping\n");
  935. if (undosm != zname)
  936. free((zvoid *)zname);
  937. if (undosm != iname)
  938. free((zvoid *)undosm);
  939. free((zvoid *)iname);
  940. free(oname);
  941. return ZE_OK;
  942. }
  943. #endif /* CMS_MVS */
  944. /* allocate space and add to list */
  945. if ((f = (struct flist far *)farmalloc(sizeof(struct flist))) == NULL ||
  946. fcount + 1 < fcount ||
  947. (f->name = malloc(strlen(name) + 1 + PAD)) == NULL)
  948. {
  949. if (f != NULL)
  950. farfree((zvoid far *)f);
  951. if (undosm != zname)
  952. free((zvoid *)undosm);
  953. free((zvoid *)iname);
  954. free((zvoid *)zname);
  955. free(oname);
  956. return ZE_MEM;
  957. }
  958. strcpy(f->name, name);
  959. f->iname = iname;
  960. f->zname = zname;
  961. #ifdef UNICODE_SUPPORT
  962. /* Unicode */
  963. f->uname = local_to_utf8_string(iname);
  964. #ifdef WIN32
  965. f->namew = NULL;
  966. f->inamew = NULL;
  967. f->znamew = NULL;
  968. if (strcmp(f->name, "-") == 0) {
  969. f->namew = local_to_wchar_string(f->name);
  970. }
  971. #endif
  972. #endif
  973. f->oname = oname;
  974. f->dosflag = dosflag;
  975. *fnxt = f;
  976. f->lst = fnxt;
  977. f->nxt = NULL;
  978. fnxt = &f->nxt;
  979. fcount++;
  980. if (name == label) {
  981. label = f->name;
  982. }
  983. }
  984. if (undosm != zname)
  985. free((zvoid *)undosm);
  986. return ZE_OK;
  987. }
  988. ulg dostime(y, n, d, h, m, s)
  989. int y; /* year */
  990. int n; /* month */
  991. int d; /* day */
  992. int h; /* hour */
  993. int m; /* minute */
  994. int s; /* second */
  995. /* Convert the date y/n/d and time h:m:s to a four byte DOS date and
  996. time (date in high two bytes, time in low two bytes allowing magnitude
  997. comparison). */
  998. {
  999. return y < 1980 ? DOSTIME_MINIMUM /* dostime(1980, 1, 1, 0, 0, 0) */ :
  1000. (((ulg)y - 1980) << 25) | ((ulg)n << 21) | ((ulg)d << 16) |
  1001. ((ulg)h << 11) | ((ulg)m << 5) | ((ulg)s >> 1);
  1002. }
  1003. ulg unix2dostime(t)
  1004. time_t *t; /* unix time to convert */
  1005. /* Return the Unix time t in DOS format, rounded up to the next two
  1006. second boundary. */
  1007. {
  1008. time_t t_even;
  1009. struct tm *s; /* result of localtime() */
  1010. t_even = (time_t)(((unsigned long)(*t) + 1) & (~1));
  1011. /* Round up to even seconds. */
  1012. s = localtime(&t_even); /* Use local time since MSDOS does. */
  1013. if (s == (struct tm *)NULL) {
  1014. /* time conversion error; use current time as emergency value
  1015. (assuming that localtime() does at least accept this value!) */
  1016. t_even = (time_t)(((unsigned long)time(NULL) + 1) & (~1));
  1017. s = localtime(&t_even);
  1018. }
  1019. return dostime(s->tm_year + 1900, s->tm_mon + 1, s->tm_mday,
  1020. s->tm_hour, s->tm_min, s->tm_sec);
  1021. }
  1022. int issymlnk(a)
  1023. ulg a; /* Attributes returned by filetime() */
  1024. /* Return true if the attributes are those of a symbolic link */
  1025. {
  1026. #ifndef QDOS
  1027. #ifdef S_IFLNK
  1028. #ifdef __human68k__
  1029. int *_dos_importlnenv(void);
  1030. if (_dos_importlnenv() == NULL)
  1031. return 0;
  1032. #endif
  1033. return ((a >> 16) & S_IFMT) == S_IFLNK;
  1034. #else /* !S_IFLNK */
  1035. return (int)a & 0; /* avoid warning on unused parameter */
  1036. #endif /* ?S_IFLNK */
  1037. #else
  1038. return 0;
  1039. #endif
  1040. }
  1041. #endif /* !UTIL */
  1042. #if (!defined(UTIL) && !defined(ZP_NEED_GEN_D2U_TIME))
  1043. /* There is no need for dos2unixtime() in the ZipUtils' code. */
  1044. # define ZP_NEED_GEN_D2U_TIME
  1045. #endif
  1046. #if ((defined(OS2) || defined(VMS)) && defined(ZP_NEED_GEN_D2U_TIME))
  1047. /* OS/2 and VMS use a special solution to handle time-stams of files. */
  1048. # undef ZP_NEED_GEN_D2U_TIME
  1049. #endif
  1050. #if (defined(W32_STATROOT_FIX) && !defined(ZP_NEED_GEN_D2U_TIME))
  1051. /* The Win32 stat()-bandaid to fix stat'ing root directories needs
  1052. * dos2unixtime() to calculate the time-stamps. */
  1053. # define ZP_NEED_GEN_D2U_TIME
  1054. #endif
  1055. #ifdef ZP_NEED_GEN_D2U_TIME
  1056. time_t dos2unixtime(dostime)
  1057. ulg dostime; /* DOS time to convert */
  1058. /* Return the Unix time_t value (GMT/UTC time) for the DOS format (local)
  1059. * time dostime, where dostime is a four byte value (date in most significant
  1060. * word, time in least significant word), see dostime() function.
  1061. */
  1062. {
  1063. struct tm *t; /* argument for mktime() */
  1064. ZCONST time_t clock = time(NULL);
  1065. t = localtime(&clock);
  1066. t->tm_isdst = -1; /* let mktime() determine if DST is in effect */
  1067. /* Convert DOS time to UNIX time_t format */
  1068. t->tm_sec = (((int)dostime) << 1) & 0x3e;
  1069. t->tm_min = (((int)dostime) >> 5) & 0x3f;
  1070. t->tm_hour = (((int)dostime) >> 11) & 0x1f;
  1071. t->tm_mday = (int)(dostime >> 16) & 0x1f;
  1072. t->tm_mon = ((int)(dostime >> 21) & 0x0f) - 1;
  1073. t->tm_year = ((int)(dostime >> 25) & 0x7f) + 80;
  1074. return mktime(t);
  1075. }
  1076. #undef ZP_NEED_GEN_D2U_TIME
  1077. #endif /* ZP_NEED_GEN_D2U_TIME */
  1078. #ifndef MACOS
  1079. int destroy(f)
  1080. char *f; /* file to delete */
  1081. /* Delete the file *f, returning non-zero on failure. */
  1082. {
  1083. return unlink(f);
  1084. }
  1085. int replace(d, s)
  1086. char *d, *s; /* destination and source file names */
  1087. /* Replace file *d by file *s, removing the old *s. Return an error code
  1088. in the ZE_ class. This function need not preserve the file attributes,
  1089. this will be done by setfileattr() later.
  1090. */
  1091. {
  1092. z_stat t; /* results of stat() */
  1093. #if defined(CMS_MVS)
  1094. /* cmsmvs.h defines FOPW_TEMP as memory(hiperspace). Since memory is
  1095. * lost at end of run, always do copy instead of rename.
  1096. */
  1097. int copy = 1;
  1098. #else
  1099. int copy = 0;
  1100. #endif
  1101. int d_exists;
  1102. #if defined(VMS) || defined(CMS_MVS)
  1103. /* stat() is broken on VMS remote files (accessed through Decnet).
  1104. * This patch allows creation of remote zip files, but is not sufficient
  1105. * to update them or compress remote files */
  1106. unlink(d);
  1107. #else /* !(VMS || CMS_MVS) */
  1108. d_exists = (LSTAT(d, &t) == 0);
  1109. if (d_exists)
  1110. {
  1111. /*
  1112. * respect existing soft and hard links!
  1113. */
  1114. if (t.st_nlink > 1
  1115. # ifdef S_IFLNK
  1116. || (t.st_mode & S_IFMT) == S_IFLNK
  1117. # endif
  1118. )
  1119. copy = 1;
  1120. else if (unlink(d))
  1121. return ZE_CREAT; /* Can't erase zip file--give up */
  1122. }
  1123. #endif /* ?(VMS || CMS_MVS) */
  1124. #ifndef CMS_MVS
  1125. if (!copy) {
  1126. if (rename(s, d)) { /* Just move s on top of d */
  1127. copy = 1; /* failed ? */
  1128. #if !defined(VMS) && !defined(ATARI) && !defined(AZTEC_C)
  1129. #if !defined(CMS_MVS) && !defined(RISCOS) && !defined(QDOS)
  1130. /* For VMS, ATARI, AMIGA Aztec, VM_CMS, MVS, RISCOS,
  1131. always assume that failure is EXDEV */
  1132. if (errno != EXDEV
  1133. # ifdef THEOS
  1134. && errno != EEXIST
  1135. # else
  1136. # ifdef ENOTSAM
  1137. && errno != ENOTSAM /* Used at least on Turbo C */
  1138. # endif
  1139. # endif
  1140. ) return ZE_CREAT;
  1141. #endif /* !CMS_MVS && !RISCOS */
  1142. #endif /* !VMS && !ATARI && !AZTEC_C */
  1143. }
  1144. }
  1145. #endif /* !CMS_MVS */
  1146. if (copy) {
  1147. FILE *f, *g; /* source and destination files */
  1148. int r; /* temporary variable */
  1149. #ifdef RISCOS
  1150. if (SWI_OS_FSControl_26(s,d,0xA1)!=NULL) {
  1151. #endif
  1152. /* Use zfopen for almost all opens where fopen is used. For
  1153. most OS that support large files we use the 64-bit file
  1154. environment and zfopen maps to fopen, but this allows
  1155. tweeking ports that don't do that. 7/24/04 */
  1156. if ((f = zfopen(s, FOPR)) == NULL) {
  1157. fprintf(mesg," replace: can't open %s\n", s);
  1158. return ZE_TEMP;
  1159. }
  1160. if ((g = zfopen(d, FOPW)) == NULL)
  1161. {
  1162. fclose(f);
  1163. return ZE_CREAT;
  1164. }
  1165. r = fcopy(f, g, (ulg)-1L);
  1166. fclose(f);
  1167. if (fclose(g) || r != ZE_OK)
  1168. {
  1169. unlink(d);
  1170. return r ? (r == ZE_TEMP ? ZE_WRITE : r) : ZE_WRITE;
  1171. }
  1172. unlink(s);
  1173. #ifdef RISCOS
  1174. }
  1175. #endif
  1176. }
  1177. return ZE_OK;
  1178. }
  1179. #endif /* !MACOS */
  1180. int getfileattr(f)
  1181. char *f; /* file path */
  1182. /* Return the file attributes for file f or 0 if failure */
  1183. {
  1184. #ifdef __human68k__
  1185. struct _filbuf buf;
  1186. return _dos_files(&buf, f, 0xff) < 0 ? 0x20 : buf.atr;
  1187. #else
  1188. z_stat s;
  1189. return SSTAT(f, &s) == 0 ? (int) s.st_mode : 0;
  1190. #endif
  1191. }
  1192. int setfileattr(f, a)
  1193. char *f; /* file path */
  1194. int a; /* attributes returned by getfileattr() */
  1195. /* Give the file f the attributes a, return non-zero on failure */
  1196. {
  1197. #if defined(TOPS20) || defined (CMS_MVS)
  1198. return 0;
  1199. #else
  1200. #ifdef __human68k__
  1201. return _dos_chmod(f, a) < 0 ? -1 : 0;
  1202. #else
  1203. return chmod(f, a);
  1204. #endif
  1205. #endif
  1206. }
  1207. /* tempname */
  1208. #ifndef VMS /* VMS-specific function is in VMS.C. */
  1209. char *tempname(zip)
  1210. char *zip; /* path name of zip file to generate temp name for */
  1211. /* Return a temporary file name in its own malloc'ed space, using tempath. */
  1212. {
  1213. char *t = zip; /* malloc'ed space for name (use zip to avoid warning) */
  1214. # ifdef CMS_MVS
  1215. if ((t = malloc(strlen(tempath) + L_tmpnam + 2)) == NULL)
  1216. return NULL;
  1217. # ifdef VM_CMS
  1218. tmpnam(t);
  1219. /* Remove filemode and replace with tempath, if any. */
  1220. /* Otherwise A-disk is used by default */
  1221. *(strrchr(t, ' ')+1) = '\0';
  1222. if (tempath!=NULL)
  1223. strcat(t, tempath);
  1224. return t;
  1225. # else /* !VM_CMS */
  1226. /* For MVS */
  1227. tmpnam(t);
  1228. if (tempath != NULL)
  1229. {
  1230. int l1 = strlen(t);
  1231. char *dot;
  1232. if (*t == '\'' && *(t+l1-1) == '\'' && (dot = strchr(t, '.')))
  1233. {
  1234. /* MVS and not OE. tmpnam() returns quoted string of 5 qualifiers.
  1235. * First is HLQ, rest are timestamps. User can only replace HLQ.
  1236. */
  1237. int l2 = strlen(tempath);
  1238. if (strchr(tempath, '.') || l2 < 1 || l2 > 8)
  1239. ziperr(ZE_PARMS, "On MVS and not OE, tempath (-b) can only be HLQ");
  1240. memmove(t+1+l2, dot, l1+1-(dot-t)); /* shift dot ready for new hlq */
  1241. memcpy(t+1, tempath, l2); /* insert new hlq */
  1242. }
  1243. else
  1244. {
  1245. /* MVS and probably OE. tmpnam() returns filename based on TMPDIR,
  1246. * no point in even attempting to change it. User should modify TMPDIR
  1247. * instead.
  1248. */
  1249. zipwarn("MVS, assumed to be OE, change TMPDIR instead of option -b: ",
  1250. tempath);
  1251. }
  1252. }
  1253. return t;
  1254. # endif /* !VM_CMS */
  1255. # else /* !CMS_MVS */
  1256. # ifdef TANDEM
  1257. char cur_subvol [FILENAME_MAX];
  1258. char temp_subvol [FILENAME_MAX];
  1259. char *zptr;
  1260. char *ptr;
  1261. char *cptr = &cur_subvol[0];
  1262. char *tptr = &temp_subvol[0];
  1263. short err;
  1264. FILE *tempf;
  1265. int attempts;
  1266. t = (char *)malloc(NAMELEN); /* malloc here as you cannot free */
  1267. /* tmpnam allocated storage later */
  1268. zptr = strrchr(zip, TANDEM_DELIMITER);
  1269. if (zptr != NULL) {
  1270. /* ZIP file specifies a Subvol so make temp file there so it can just
  1271. be renamed at end */
  1272. *tptr = *cptr = '\0';
  1273. strcat(cptr, getenv("DEFAULTS"));
  1274. strncat(tptr, zip, _min(FILENAME_MAX, (zptr - zip)) ); /* temp subvol */
  1275. strncat(t, zip, _min(NAMELEN, ((zptr - zip) + 1)) ); /* temp stem */
  1276. err = chvol(tptr);
  1277. ptr = t + strlen(t); /* point to end of stem */
  1278. }
  1279. else
  1280. ptr = t;
  1281. /* If two zips are running in same subvol then we can get contention problems
  1282. with the temporary filename. As a work around we attempt to create
  1283. the file here, and if it already exists we get a new temporary name */
  1284. attempts = 0;
  1285. do {
  1286. attempts++;
  1287. tmpnam(ptr); /* Add filename */
  1288. tempf = zfopen(ptr, FOPW_TMP); /* Attempt to create file */
  1289. } while (tempf == NULL && attempts < 100);
  1290. if (attempts >= 100) {
  1291. ziperr(ZE_TEMP, "Could not get unique temp file name");
  1292. }
  1293. fclose(tempf);
  1294. if (zptr != NULL) {
  1295. err = chvol(cptr); /* Put ourself back to where we came in */
  1296. }
  1297. return t;
  1298. # else /* !CMS_MVS && !TANDEM */
  1299. /*
  1300. * Do something with TMPDIR, TMP, TEMP ????
  1301. */
  1302. if (tempath != NULL)
  1303. {
  1304. if ((t = malloc(strlen(tempath) + 12)) == NULL)
  1305. return NULL;
  1306. strcpy(t, tempath);
  1307. # if (!defined(VMS) && !defined(TOPS20))
  1308. # ifdef MSDOS
  1309. {
  1310. char c = (char)lastchar(t);
  1311. if (c != '/' && c != ':' && c != '\\')
  1312. strcat(t, "/");
  1313. }
  1314. # else
  1315. # ifdef AMIGA
  1316. {
  1317. char c = (char)lastchar(t);
  1318. if (c != '/' && c != ':')
  1319. strcat(t, "/");
  1320. }
  1321. # else /* !AMIGA */
  1322. # ifdef RISCOS
  1323. if (lastchar(t) != '.')
  1324. strcat(t, ".");
  1325. # else /* !RISCOS */
  1326. # ifdef QDOS
  1327. if (lastchar(t) != '_')
  1328. strcat(t, "_");
  1329. # else
  1330. if (lastchar(t) != '/')
  1331. strcat(t, "/");
  1332. # endif /* ?QDOS */
  1333. # endif /* ?RISCOS */
  1334. # endif /* ?AMIGA */
  1335. # endif /* ?MSDOS */
  1336. # endif /* !VMS && !TOPS20 */
  1337. }
  1338. else
  1339. {
  1340. if ((t = malloc(12)) == NULL)
  1341. return NULL;
  1342. *t = 0;
  1343. }
  1344. # ifdef NO_MKTEMP
  1345. {
  1346. char *p = t + strlen(t);
  1347. sprintf(p, "%08lx", (ulg)time(NULL));
  1348. return t;
  1349. }
  1350. # else
  1351. strcat(t, "ziXXXXXX"); /* must use lowercase for Linux dos file system */
  1352. # if defined(UNIX) && !defined(NO_MKSTEMP)
  1353. /* tempname should not be called */
  1354. return t;
  1355. # else
  1356. return mktemp(t);
  1357. # endif
  1358. # endif /* NO_MKTEMP */
  1359. # endif /* TANDEM */
  1360. # endif /* CMS_MVS */
  1361. }
  1362. #endif /* !VMS */
  1363. int fcopy(f, g, n)
  1364. FILE *f, *g; /* source and destination files */
  1365. /* now use uzoff_t for all file sizes 5/14/05 CS */
  1366. uzoff_t n; /* number of bytes to copy or -1 for all */
  1367. /* Copy n bytes from file *f to file *g, or until EOF if (zoff_t)n == -1.
  1368. Return an error code in the ZE_ class. */
  1369. {
  1370. char *b; /* malloc'ed buffer for copying */
  1371. extent k; /* result of fread() */
  1372. uzoff_t m; /* bytes copied so far */
  1373. if ((b = malloc(CBSZ)) == NULL)
  1374. return ZE_MEM;
  1375. m = 0;
  1376. while (n == (uzoff_t)(-1L) || m < n)
  1377. {
  1378. if ((k = fread(b, 1, n == (uzoff_t)(-1) ?
  1379. CBSZ : (n - m < CBSZ ? (extent)(n - m) : CBSZ), f)) == 0)
  1380. {
  1381. if (ferror(f))
  1382. {
  1383. free((zvoid *)b);
  1384. return ZE_READ;
  1385. }
  1386. else
  1387. break;
  1388. }
  1389. if (fwrite(b, 1, k, g) != k)
  1390. {
  1391. free((zvoid *)b);
  1392. fprintf(mesg," fcopy: write error\n");
  1393. return ZE_TEMP;
  1394. }
  1395. m += k;
  1396. }
  1397. free((zvoid *)b);
  1398. return ZE_OK;
  1399. }
  1400. /* from zipfile.c */
  1401. #ifdef THEOS
  1402. /* Macros cause stack overflow in compiler */
  1403. ush SH(uch* p) { return ((ush)(uch)((p)[0]) | ((ush)(uch)((p)[1]) << 8)); }
  1404. ulg LG(uch* p) { return ((ulg)(SH(p)) | ((ulg)(SH((p)+2)) << 16)); }
  1405. #else /* !THEOS */
  1406. /* Macros for converting integers in little-endian to machine format */
  1407. # define SH(a) ((ush)(((ush)(uch)(a)[0]) | (((ush)(uch)(a)[1]) << 8)))
  1408. # define LG(a) ((ulg)SH(a) | ((ulg)SH((a)+2) << 16))
  1409. # ifdef ZIP64_SUPPORT /* zip64 support 08/31/2003 R.Nausedat */
  1410. # define LLG(a) ((zoff_t)LG(a) | ((zoff_t)LG((a)+4) << 32))
  1411. # endif
  1412. #endif /* ?THEOS */
  1413. /* always copies from global in_file to global output file y */
  1414. int bfcopy(n)
  1415. /* now use uzoff_t for all file sizes 5/14/05 CS */
  1416. uzoff_t n; /* number of bytes to copy or -1 for all */
  1417. /* Copy n bytes from in_file to out_file, or until EOF if (zoff_t)n == -1.
  1418. Normally we have the compressed size from either the central directory
  1419. entry or the local header.
  1420. If n != -1 and EOF, close current split and open next and continue
  1421. copying.
  1422. If n == -2, copy until find the extended header (data descriptor). Only
  1423. used for -FF when no size available.
  1424. If fix == 1 calculate CRC of input entry and verify matches.
  1425. If fix == 2 and this entry using data descriptor keep a sliding
  1426. window in the buffer for looking for signature.
  1427. Return an error code in the ZE_ class. */
  1428. {
  1429. char *b; /* malloc'ed buffer for copying */
  1430. extent k; /* result of fread() */
  1431. uzoff_t m; /* bytes copied so far */
  1432. extent brd; /* bytes to read */
  1433. zoff_t data_start = 0;
  1434. zoff_t des_start = 0;
  1435. char *split_path;
  1436. extent kk;
  1437. int i;
  1438. char sbuf[4]; /* buffer for sliding signature window for fix = 2 */
  1439. int des = 0; /* this entry has data descriptor to find */
  1440. if ((b = malloc(CBSZ)) == NULL)
  1441. return ZE_MEM;
  1442. if (copy_only && !display_globaldots) {
  1443. /* initialize dot count */
  1444. dot_count = -1;
  1445. }
  1446. if (fix == 2 && n == (uzoff_t) -2) {
  1447. data_start = zftello(in_file);
  1448. for (kk = 0; kk < 4; kk++)
  1449. sbuf[kk] = 0;
  1450. des = 1;
  1451. }
  1452. des_good = 0;
  1453. m = 0;
  1454. while (des || n == (uzoff_t)(-1L) || m < n)
  1455. {
  1456. if (des || n == (uzoff_t)(-1))
  1457. brd = CBSZ;
  1458. else
  1459. brd = (n - m < CBSZ ? (extent)(n - m) : CBSZ);
  1460. des_start = zftello(in_file);
  1461. if ((k = fread(b, 1, brd, in_file)) == 0)
  1462. {
  1463. if (fix == 2 && k < brd) {
  1464. free((zvoid *)b);
  1465. return ZE_READ;
  1466. }
  1467. else if (ferror(in_file))
  1468. {
  1469. free((zvoid *)b);
  1470. return ZE_READ;
  1471. }
  1472. else {
  1473. break;
  1474. }
  1475. }
  1476. /* end at extended local header (data descriptor) signature */
  1477. if (des) {
  1478. des_crc = 0;
  1479. des_csize = 0;
  1480. des_usize = 0;
  1481. /* If first 4 bytes in buffer are data descriptor signature then
  1482. try to read the data descriptor.
  1483. If not, scan for signature and break if found, let bfwrite flush
  1484. the data and then next read should put the data descriptor at
  1485. the beginning of the buffer.
  1486. */
  1487. if (
  1488. (b[0] != 0x50 /*'P' except EBCDIC*/ ||
  1489. b[1] != 0x4b /*'K' except EBCDIC*/ ||
  1490. b[2] != '\07' ||
  1491. b[3] != '\010')) {
  1492. /* buffer is not start of data descriptor */
  1493. for (kk = 0; kk < k; kk++) {
  1494. /* add byte to end of sbuf */
  1495. for (i = 0; i < 3; i++)
  1496. sbuf[i] = sbuf[i + 1];
  1497. sbuf[3] = b[kk];
  1498. /* see if this is signature */
  1499. if (
  1500. (sbuf[0] == 0x50 /*'P' except EBCDIC*/ &&
  1501. sbuf[1] == 0x4b /*'K' except EBCDIC*/ &&
  1502. sbuf[2] == '\07' &&
  1503. sbuf[3] == '\010')) {
  1504. kk -= 3;
  1505. if (zfseeko(in_file, bytes_this_split + kk, SEEK_SET) != 0) {
  1506. /* seek error */
  1507. ZIPERR(ZE_READ, "seek failed reading descriptor");
  1508. }
  1509. des_start = zftello(in_file);
  1510. k = kk;
  1511. break;
  1512. }
  1513. }
  1514. }
  1515. else
  1516. /* signature at start of buffer */
  1517. {
  1518. des_good = 0;
  1519. #ifdef ZIP64_SUPPORT
  1520. if (zip64_entry) {
  1521. /* read Zip64 data descriptor */
  1522. if (k < 24) {
  1523. /* not enough bytes, so can't be data descriptor
  1524. as data descriptors can't be split across splits
  1525. */
  1526. }
  1527. else
  1528. {
  1529. /* read the Zip64 descriptor */
  1530. des_crc = LG(b + 4);
  1531. des_csize = LLG(b + 8);
  1532. des_usize = LLG(b + 16);
  1533. /* if this is the right data descriptor then the sizes should match */
  1534. if ((uzoff_t)des_start - (uzoff_t)data_start != des_csize) {
  1535. /* apparently this signature does not go with this data so skip */
  1536. /* write out signature as data */
  1537. k = 4;
  1538. if (zfseeko(in_file, des_start + k, SEEK_SET) != 0) {
  1539. /* seek error */
  1540. ZIPERR(ZE_READ, "seek failed reading descriptor");
  1541. }
  1542. if (bfwrite(b, 1, k, BFWRITE_DATA) != k)
  1543. {
  1544. free((zvoid *)b);
  1545. fprintf(mesg," fcopy: write error\n");
  1546. return ZE_TEMP;
  1547. }
  1548. m += k;
  1549. continue;
  1550. }
  1551. else
  1552. {
  1553. /* apparently this is the correct data descriptor */
  1554. /* we should check the CRC but would need to inflate
  1555. the data */
  1556. /* skip descriptor as will write out later */
  1557. des_good = 1;
  1558. k = 24;
  1559. data_start = zftello(in_file);
  1560. if (zfseeko(in_file, des_start + k, SEEK_SET) != 0) {
  1561. /* seek error */
  1562. ZIPERR(ZE_READ, "seek failed reading descriptor");
  1563. }
  1564. data_start = zftello(in_file);
  1565. }
  1566. }
  1567. }
  1568. else
  1569. #endif
  1570. {
  1571. /* read standard data descriptor */
  1572. if (k < 16) {
  1573. /* not enough bytes, so can't be data descriptor
  1574. as data descriptors can't be split across splits
  1575. */
  1576. }
  1577. else
  1578. {
  1579. /* read the descriptor */
  1580. des_crc = LG(b + 4);
  1581. des_csize = LG(b + 8);
  1582. des_usize = LG(b + 12);
  1583. /* if this is the right data descriptor then the sizes should match */
  1584. if ((uzoff_t)des_start - (uzoff_t)data_start != des_csize) {
  1585. /* apparently this signature does not go with this data so skip */
  1586. /* write out signature as data */
  1587. k = 4;
  1588. if (zfseeko(in_file, des_start + k, SEEK_SET) != 0) {
  1589. /* seek error */
  1590. ZIPERR(ZE_READ, "seek failed reading descriptor");
  1591. }
  1592. if (bfwrite(b, 1, k, BFWRITE_DATA) != k)
  1593. {
  1594. free((zvoid *)b);
  1595. fprintf(mesg," fcopy: write error\n");
  1596. return ZE_TEMP;
  1597. }
  1598. m += k;
  1599. continue;
  1600. }
  1601. else
  1602. {
  1603. /* apparently this is the correct data descriptor */
  1604. /* we should check the CRC but this does not work for
  1605. encrypted data */
  1606. /* skip descriptor as will write out later */
  1607. des_good = 1;
  1608. data_start = zftello(in_file);
  1609. k = 16;
  1610. if (zfseeko(in_file, des_start + k, SEEK_SET) != 0) {
  1611. /* seek error */
  1612. ZIPERR(ZE_READ, "seek failed reading descriptor");
  1613. }
  1614. data_start = zftello(in_file);
  1615. }
  1616. }
  1617. }
  1618. }
  1619. }
  1620. if (des_good) {
  1621. /* skip descriptor as will write out later */
  1622. } else {
  1623. /* write out apparently wrong descriptor as data */
  1624. if (bfwrite(b, 1, k, BFWRITE_DATA) != k)
  1625. {
  1626. free((zvoid *)b);
  1627. fprintf(mesg," fcopy: write error\n");
  1628. return ZE_TEMP;
  1629. }
  1630. m += k;
  1631. }
  1632. if (copy_only && !display_globaldots) {
  1633. if (dot_size > 0) {
  1634. /* initial space */
  1635. if (noisy && dot_count == -1) {
  1636. #ifndef WINDLL
  1637. putc(' ', mesg);
  1638. fflush(mesg);
  1639. #else
  1640. fprintf(stdout,"%c",' ');
  1641. #endif
  1642. dot_count++;
  1643. }
  1644. dot_count += k;
  1645. if (dot_size <= dot_count) dot_count = 0;
  1646. }
  1647. if ((verbose || noisy) && dot_size && !dot_count) {
  1648. #ifndef WINDLL
  1649. putc('.', mesg);
  1650. fflush(mesg);
  1651. #else
  1652. fprintf(stdout,"%c",'.');
  1653. #endif
  1654. mesg_line_started = 1;
  1655. }
  1656. }
  1657. if (des_good)
  1658. break;
  1659. if (des)
  1660. continue;
  1661. if ((des || n != (uzoff_t)(-1L)) && m < n && feof(in_file)) {
  1662. /* open next split */
  1663. current_in_disk++;
  1664. if (current_in_disk >= total_disks) {
  1665. /* done */
  1666. break;
  1667. } else if (current_in_disk == total_disks - 1) {
  1668. /* last disk is archive.zip */
  1669. if ((split_path = malloc(strlen(in_path) + 1)) == NULL) {
  1670. zipwarn("reading archive: ", in_path);
  1671. return ZE_MEM;
  1672. }
  1673. strcpy(split_path, in_path);
  1674. } else {
  1675. /* other disks are archive.z01, archive.z02, ... */
  1676. split_path = get_in_split_path(in_path, current_in_disk);
  1677. }
  1678. fclose(in_file);
  1679. /* open the split */
  1680. while ((in_file = zfopen(split_path, FOPR)) == NULL) {
  1681. int r = 0;
  1682. /* could not open split */
  1683. if (fix == 1 && skip_this_disk) {
  1684. free(split_path);
  1685. free((zvoid *)b);
  1686. return ZE_FORM;
  1687. }
  1688. /* Ask for directory with split. Updates in_path */
  1689. r = ask_for_split_read_path(current_in_disk);
  1690. if (r == ZE_ABORT) {
  1691. zipwarn("could not find split: ", split_path);
  1692. free(split_path);
  1693. free((zvoid *)b);
  1694. return ZE_ABORT;
  1695. }
  1696. if (r == ZE_EOF) {
  1697. zipmessage_nl("", 1);
  1698. zipwarn("user ended reading - closing archive", "");
  1699. free(split_path);
  1700. free((zvoid *)b);
  1701. return ZE_EOF;
  1702. }
  1703. if (fix == 2 && skip_this_disk) {
  1704. /* user asked to skip this disk */
  1705. zipwarn("skipping split file: ", split_path);
  1706. current_in_disk++;
  1707. }
  1708. if (current_in_disk == total_disks - 1) {
  1709. /* last disk is archive.zip */
  1710. if ((split_path = malloc(strlen(in_path) + 1)) == NULL) {
  1711. zipwarn("reading archive: ", in_path);
  1712. return ZE_MEM;
  1713. }
  1714. strcpy(split_path, in_path);
  1715. } else {
  1716. /* other disks are archive.z01, archive.z02, ... */
  1717. split_path = get_in_split_path(zipfile, current_in_disk);
  1718. }
  1719. }
  1720. if (fix == 2 && skip_this_disk) {
  1721. /* user asked to skip this disk */
  1722. free(split_path);
  1723. free((zvoid *)b);
  1724. return ZE_FORM;
  1725. }
  1726. free(split_path);
  1727. }
  1728. }
  1729. free((zvoid *)b);
  1730. return ZE_OK;
  1731. }
  1732. #ifdef NO_RENAME
  1733. int rename(from, to)
  1734. ZCONST char *from;
  1735. ZCONST char *to;
  1736. {
  1737. unlink(to);
  1738. if (link(from, to) == -1)
  1739. return -1;
  1740. if (unlink(from) == -1)
  1741. return -1;
  1742. return 0;
  1743. }
  1744. #endif /* NO_RENAME */
  1745. #ifdef ZMEM
  1746. /************************/
  1747. /* Function memset() */
  1748. /************************/
  1749. /*
  1750. * memset - for systems without it
  1751. * bill davidsen - March 1990
  1752. */
  1753. char *
  1754. memset(buf, init, len)
  1755. register char *buf; /* buffer loc */
  1756. register int init; /* initializer */
  1757. register unsigned int len; /* length of the buffer */
  1758. {
  1759. char *start;
  1760. start = buf;
  1761. while (len--) *(buf++) = init;
  1762. return(start);
  1763. }
  1764. /************************/
  1765. /* Function memcpy() */
  1766. /************************/
  1767. char *
  1768. memcpy(dst,src,len) /* v2.0f */
  1769. register char *dst, *src;
  1770. register unsigned int len;
  1771. {
  1772. char *start;
  1773. start = dst;
  1774. while (len--)
  1775. *dst++ = *src++;
  1776. return(start);
  1777. }
  1778. /************************/
  1779. /* Function memcmp() */
  1780. /************************/
  1781. int
  1782. memcmp(b1,b2,len) /* jpd@usl.edu -- 11/16/90 */
  1783. register char *b1, *b2;
  1784. register unsigned int len;
  1785. {
  1786. if (len) do { /* examine each byte (if any) */
  1787. if (*b1++ != *b2++)
  1788. return (*((uch *)b1-1) - *((uch *)b2-1)); /* exit when miscompare */
  1789. } while (--len);
  1790. return(0); /* no miscompares, yield 0 result */
  1791. }
  1792. #endif /* ZMEM */
  1793. /*------------------------------------------------------------------
  1794. * Split archives
  1795. */
  1796. /* ask_for_split_read_path
  1797. *
  1798. * If the next split file is not in the current directory, ask
  1799. * the user where it is.
  1800. *
  1801. * in_path is the base path for reading splits and is usually
  1802. * the same as zipfile. The path in in_path must be the archive
  1803. * file ending in .zip as this is assumed by get_in_split_path().
  1804. *
  1805. * Updates in_path if changed. Returns ZE_OK if OK or ZE_ABORT if
  1806. * user cancels reading archive.
  1807. *
  1808. * If fix = 1 then allow skipping disk (user may not have it).
  1809. */
  1810. #define SPLIT_MAXPATH (FNMAX + 4010)
  1811. int ask_for_split_read_path(current_disk)
  1812. ulg current_disk;
  1813. {
  1814. FILE *f;
  1815. int is_readable = 0;
  1816. int i;
  1817. char *split_dir = NULL;
  1818. char *archive_name = NULL;
  1819. char *split_name = NULL;
  1820. char *split_path = NULL;
  1821. char buf[SPLIT_MAXPATH + 100];
  1822. /* get split path */
  1823. split_path = get_in_split_path(in_path, current_disk);
  1824. /* get the directory */
  1825. if ((split_dir = malloc(strlen(in_path) + 40)) == NULL) {
  1826. ZIPERR(ZE_MEM, "split path");
  1827. }
  1828. strcpy(split_dir, in_path);
  1829. /* remove any name at end */
  1830. for (i = strlen(split_dir) - 1; i >= 0; i--) {
  1831. if (split_dir[i] == '/' || split_dir[i] == '\\'
  1832. || split_dir[i] == ':') {
  1833. split_dir[i + 1] = '\0';
  1834. break;
  1835. }
  1836. }
  1837. if (i < 0)
  1838. split_dir[0] = '\0';
  1839. /* get the name of the archive */
  1840. if ((archive_name = malloc(strlen(in_path) + 1)) == NULL) {
  1841. ZIPERR(ZE_MEM, "split path");
  1842. }
  1843. if (strlen(in_path) == strlen(split_dir)) {
  1844. archive_name[0] = '\0';
  1845. } else {
  1846. strcpy(archive_name, in_path + strlen(split_dir));
  1847. }
  1848. /* get the name of the split */
  1849. if ((split_name = malloc(strlen(split_path) + 1)) == NULL) {
  1850. ZIPERR(ZE_MEM, "split path");
  1851. }
  1852. if (strlen(in_path) == strlen(split_dir)) {
  1853. split_name[0] = '\0';
  1854. } else {
  1855. strcpy(split_name, split_path + strlen(split_dir));
  1856. }
  1857. if (i < 0) {
  1858. strcpy(split_dir, "(current directory)");
  1859. }
  1860. fprintf(mesg, "\n\nCould not find:\n");
  1861. fprintf(mesg, " %s\n", split_path);
  1862. /*
  1863. fprintf(mesg, "Please enter the path directory (. for cur dir) where\n");
  1864. fprintf(mesg, " %s\n", split_name);
  1865. fprintf(mesg, "is located\n");
  1866. */
  1867. for (;;) {
  1868. if (is_readable) {
  1869. fprintf(mesg, "\nHit c (change path to where this split file is)");
  1870. fprintf(mesg, "\n q (abort archive - quit)");
  1871. fprintf(mesg, "\n or ENTER (continue with this split): ");
  1872. } else {
  1873. if (fix == 1) {
  1874. fprintf(mesg, "\nHit c (change path to where this split file is)");
  1875. fprintf(mesg, "\n s (skip this split)");
  1876. fprintf(mesg, "\n q (abort archive - quit)");
  1877. fprintf(mesg, "\n or ENTER (try reading this split again): ");
  1878. } else if (fix == 2) {
  1879. fprintf(mesg, "\nHit c (change path to where this split file is)");
  1880. fprintf(mesg, "\n s (skip this split)");
  1881. fprintf(mesg, "\n q (abort archive - quit)");
  1882. fprintf(mesg, "\n e (end this archive - no more splits)");
  1883. fprintf(mesg, "\n z (look for .zip split - the last split)");
  1884. fprintf(mesg, "\n or ENTER (try reading this split again): ");
  1885. } else {
  1886. fprintf(mesg, "\nHit c (change path to where this split file is)");
  1887. fprintf(mesg, "\n q (abort archive - quit)");
  1888. fprintf(mesg, "\n or ENTER (try reading this split again): ");
  1889. }
  1890. }
  1891. fflush(mesg);
  1892. fgets(buf, SPLIT_MAXPATH, stdin);
  1893. /* remove any newline */
  1894. for (i = 0; buf[i]; i++) {
  1895. if (buf[i] == '\n') {
  1896. buf[i] = '\0';
  1897. break;
  1898. }
  1899. }
  1900. if (toupper(buf[0]) == 'Q') {
  1901. return ZE_ABORT;
  1902. } else if ((fix == 1 || fix == 2) && toupper(buf[0]) == 'S') {
  1903. /*
  1904. fprintf(mesg, "\nSkip this split/disk? (files in this split will not be recovered) [n/y] ");
  1905. fflush(mesg);
  1906. fgets(buf, SPLIT_MAXPATH, stdin);
  1907. if (buf[0] == 'y' || buf[0] == 'Y') {
  1908. */
  1909. skip_this_disk = current_in_disk + 1;
  1910. return ZE_FORM;
  1911. } else if (toupper(buf[0]) == 'C') {
  1912. fprintf(mesg, "\nEnter path where this split is (ENTER = same dir, . = current dir)");
  1913. fprintf(mesg, "\n: ");
  1914. fflush(mesg);
  1915. fgets(buf, SPLIT_MAXPATH, stdin);
  1916. is_readable = 0;
  1917. /* remove any newline */
  1918. for (i = 0; buf[i]; i++) {
  1919. if (buf[i] == '\n') {
  1920. buf[i] = '\0';
  1921. break;
  1922. }
  1923. }
  1924. if (buf[0] == '\0') {
  1925. /* Hit ENTER so try old path again - could be removable media was changed */
  1926. strcpy(buf, split_path);
  1927. }
  1928. } else if (fix == 2 && toupper(buf[0]) == 'E') {
  1929. /* no more splits to read */
  1930. return ZE_EOF;
  1931. } else if (fix == 2 && toupper(buf[0]) == 'Z') {
  1932. total_disks = current_disk + 1;
  1933. free(split_path);
  1934. split_path = get_in_split_path(in_path, current_disk);
  1935. buf[0] = '\0';
  1936. strncat(buf, split_path, SPLIT_MAXPATH);
  1937. }
  1938. if (strlen(buf) > 0) {
  1939. /* changing path */
  1940. /* check if user wants current directory */
  1941. if (buf[0] == '.' && buf[1] == '\0') {
  1942. buf[0] = '\0';
  1943. }
  1944. /* remove any name at end */
  1945. for (i = strlen(buf); i >= 0; i--) {
  1946. if (buf[i] == '/' || buf[i] == '\\'
  1947. || buf[i] == ':') {
  1948. buf[i + 1] = '\0';
  1949. break;
  1950. }
  1951. }
  1952. /* update base_path to newdir/split_name - in_path is the .zip file path */
  1953. free(in_path);
  1954. if (i < 0) {
  1955. /* just name so current directory */
  1956. strcpy(buf, "(current directory)");
  1957. if (archive_name == NULL) {
  1958. i = 0;
  1959. } else {
  1960. i = strlen(archive_name);
  1961. }
  1962. if ((in_path = malloc(strlen(archive_name) + 40)) == NULL) {
  1963. ZIPERR(ZE_MEM, "split path");
  1964. }
  1965. strcpy(in_path, archive_name);
  1966. } else {
  1967. /* not the current directory */
  1968. /* remove any name at end */
  1969. for (i = strlen(buf); i >= 0; i--) {
  1970. if (buf[i] == '/') {
  1971. buf[i + 1] = '\0';
  1972. break;
  1973. }
  1974. }
  1975. if (i < 0) {
  1976. buf[0] = '\0';
  1977. }
  1978. if ((in_path = malloc(strlen(buf) + strlen(archive_name) + 40)) == NULL) {
  1979. ZIPERR(ZE_MEM, "split path");
  1980. }
  1981. strcpy(in_path, buf);
  1982. strcat(in_path, archive_name);
  1983. }
  1984. free(split_path);
  1985. /* get split path */
  1986. split_path = get_in_split_path(in_path, current_disk);
  1987. free(split_dir);
  1988. if ((split_dir = malloc(strlen(in_path) + 40)) == NULL) {
  1989. ZIPERR(ZE_MEM, "split path");
  1990. }
  1991. strcpy(split_dir, in_path);
  1992. /* remove any name at end */
  1993. for (i = strlen(split_dir); i >= 0; i--) {
  1994. if (split_dir[i] == '/') {
  1995. split_dir[i + 1] = '\0';
  1996. break;
  1997. }
  1998. }
  1999. /* try to open it */
  2000. if ((f = fopen(split_path, "r")) == NULL) {
  2001. fprintf(mesg, "\nCould not find or open\n");
  2002. fprintf(mesg, " %s\n", split_path);
  2003. /*
  2004. fprintf(mesg, "Please enter the path (. for cur dir) where\n");
  2005. fprintf(mesg, " %s\n", split_name);
  2006. fprintf(mesg, "is located\n");
  2007. */
  2008. continue;
  2009. }
  2010. fclose(f);
  2011. is_readable = 1;
  2012. fprintf(mesg, "Found: %s\n", split_path);
  2013. } else {
  2014. /* try to open it */
  2015. if ((f = fopen(split_path, "r")) == NULL) {
  2016. fprintf(mesg, "\nCould not find or open\n");
  2017. fprintf(mesg, " %s\n", split_path);
  2018. /*
  2019. fprintf(mesg, "Please enter the path (. for cur dir) where\n");
  2020. fprintf(mesg, " %s\n", split_name);
  2021. fprintf(mesg, "is located\n");
  2022. */
  2023. continue;
  2024. }
  2025. fclose(f);
  2026. is_readable = 1;
  2027. fprintf(mesg, "\nFound: %s\n", split_path);
  2028. break;
  2029. }
  2030. }
  2031. free(archive_name);
  2032. free(split_dir);
  2033. free(split_name);
  2034. return ZE_OK;
  2035. }
  2036. /* ask_for_split_write_path
  2037. *
  2038. * Verify the directory for the next split. Called
  2039. * when -sp is used to pause between writing splits.
  2040. *
  2041. * Updates out_path and return 1 if OK or 0 if cancel
  2042. */
  2043. int ask_for_split_write_path(current_disk)
  2044. ulg current_disk;
  2045. {
  2046. unsigned int num = (unsigned int)current_disk + 1;
  2047. int i;
  2048. char *split_dir = NULL;
  2049. char *split_name = NULL;
  2050. char buf[FNMAX + 40];
  2051. /* get the directory */
  2052. if ((split_dir = malloc(strlen(out_path) + 40)) == NULL) {
  2053. ZIPERR(ZE_MEM, "split path");
  2054. }
  2055. strcpy(split_dir, out_path);
  2056. /* remove any name at end */
  2057. for (i = strlen(split_dir); i >= 0; i--) {
  2058. if (split_dir[i] == '/' || split_dir[i] == '\\'
  2059. || split_dir[i] == ':') {
  2060. split_dir[i + 1] = '\0';
  2061. break;
  2062. }
  2063. }
  2064. /* get the name of the split */
  2065. if ((split_name = malloc(strlen(out_path) + 1)) == NULL) {
  2066. ZIPERR(ZE_MEM, "split path");
  2067. }
  2068. if (strlen(out_path) == strlen(split_dir)) {
  2069. split_name[0] = '\0';
  2070. } else {
  2071. strcpy(split_name, out_path + strlen(split_dir));
  2072. }
  2073. if (i < 0) {
  2074. strcpy(split_dir, "(current directory)");
  2075. }
  2076. if (mesg_line_started)
  2077. fprintf(mesg, "\n");
  2078. fprintf(mesg, "\nOpening disk %d\n", num);
  2079. fprintf(mesg, "Hit ENTER to write to default path of\n");
  2080. fprintf(mesg, " %s\n", split_dir);
  2081. fprintf(mesg, "or enter a new directory path (. for cur dir) and hit ENTER\n");
  2082. for (;;) {
  2083. fprintf(mesg, "\nPath (or hit ENTER to continue): ");
  2084. fflush(mesg);
  2085. fgets(buf, FNMAX, stdin);
  2086. /* remove any newline */
  2087. for (i = 0; buf[i]; i++) {
  2088. if (buf[i] == '\n') {
  2089. buf[i] = '\0';
  2090. break;
  2091. }
  2092. }
  2093. if (strlen(buf) > 0) {
  2094. /* changing path */
  2095. /* current directory */
  2096. if (buf[0] == '.' && buf[1] == '\0') {
  2097. buf[0] = '\0';
  2098. }
  2099. /* remove any name at end */
  2100. for (i = strlen(buf); i >= 0; i--) {
  2101. if (buf[i] == '/' || buf[i] == '\\'
  2102. || buf[i] == ':') {
  2103. buf[i + 1] = '\0';
  2104. break;
  2105. }
  2106. }
  2107. /* update out_path to newdir/split_name */
  2108. free(out_path);
  2109. if (i < 0) {
  2110. /* just name so current directory */
  2111. strcpy(buf, "(current directory)");
  2112. if (split_name == NULL) {
  2113. i = 0;
  2114. } else {
  2115. i = strlen(split_name);
  2116. }
  2117. if ((out_path = malloc(strlen(split_name) + 40)) == NULL) {
  2118. ZIPERR(ZE_MEM, "split path");
  2119. }
  2120. strcpy(out_path, split_name);
  2121. } else {
  2122. /* not the current directory */
  2123. /* remove any name at end */
  2124. for (i = strlen(buf); i >= 0; i--) {
  2125. if (buf[i] == '/') {
  2126. buf[i + 1] = '\0';
  2127. break;
  2128. }
  2129. }
  2130. if (i < 0) {
  2131. buf[0] = '\0';
  2132. }
  2133. if ((out_path = malloc(strlen(buf) + strlen(split_name) + 40)) == NULL) {
  2134. ZIPERR(ZE_MEM, "split path");
  2135. }
  2136. strcpy(out_path, buf);
  2137. strcat(out_path, split_name);
  2138. }
  2139. fprintf(mesg, "Writing to:\n %s\n", buf);
  2140. free(split_name);
  2141. free(split_dir);
  2142. if ((split_dir = malloc(strlen(out_path) + 40)) == NULL) {
  2143. ZIPERR(ZE_MEM, "split path");
  2144. }
  2145. strcpy(split_dir, out_path);
  2146. /* remove any name at end */
  2147. for (i = strlen(split_dir); i >= 0; i--) {
  2148. if (split_dir[i] == '/') {
  2149. split_dir[i + 1] = '\0';
  2150. break;
  2151. }
  2152. }
  2153. if ((split_name = malloc(strlen(out_path) + 1)) == NULL) {
  2154. ZIPERR(ZE_MEM, "split path");
  2155. }
  2156. strcpy(split_name, out_path + strlen(split_dir));
  2157. } else {
  2158. break;
  2159. }
  2160. }
  2161. free(split_dir);
  2162. free(split_name);
  2163. /* for now no way out except Ctrl C */
  2164. return 1;
  2165. }
  2166. /* split_name
  2167. *
  2168. * get name of split being read
  2169. */
  2170. char *get_in_split_path(base_path, disk_number)
  2171. char *base_path;
  2172. ulg disk_number;
  2173. {
  2174. char *split_path = NULL;
  2175. int base_len = 0;
  2176. int path_len = 0;
  2177. ulg num = disk_number + 1;
  2178. char ext[6];
  2179. #ifdef VMS
  2180. int vers_len; /* File version length. */
  2181. char *vers_ptr; /* File version string. */
  2182. #endif /* def VMS */
  2183. /*
  2184. * A split has extension z01, z02, ..., z99, z100, z101, ... z999
  2185. * We currently support up to .z99999
  2186. * WinZip will also read .100, .101, ... but AppNote 6.2.2 uses above
  2187. * so use that. Means on DOS can only have 100 splits.
  2188. */
  2189. if (num == total_disks) {
  2190. /* last disk is base path */
  2191. if ((split_path = malloc(strlen(base_path) + 1)) == NULL) {
  2192. ZIPERR(ZE_MEM, "base path");
  2193. }
  2194. strcpy(split_path, base_path);
  2195. return split_path;
  2196. } else {
  2197. if (num > 99999) {
  2198. ZIPERR(ZE_BIG, "More than 99999 splits needed");
  2199. }
  2200. sprintf(ext, "z%02lu", num);
  2201. }
  2202. /* create path for this split - zip.c checked for .zip extension */
  2203. base_len = strlen(base_path) - 3;
  2204. path_len = base_len + strlen(ext);
  2205. #ifdef VMS
  2206. /* On VMS, locate the file version, and adjust base_len accordingly.
  2207. Note that path_len is correct, as-is.
  2208. */
  2209. vers_ptr = vms_file_version( base_path);
  2210. vers_len = strlen( vers_ptr);
  2211. base_len -= vers_len;
  2212. #endif /* def VMS */
  2213. if ((split_path = malloc(path_len + 1)) == NULL) {
  2214. ZIPERR(ZE_MEM, "split path");
  2215. }
  2216. /* copy base_path except for end zip */
  2217. strcpy(split_path, base_path);
  2218. split_path[base_len] = '\0';
  2219. /* add extension */
  2220. strcat(split_path, ext);
  2221. #ifdef VMS
  2222. /* On VMS, append (preserve) the file version. */
  2223. strcat(split_path, vers_ptr);
  2224. #endif /* def VMS */
  2225. return split_path;
  2226. }
  2227. /* split_name
  2228. *
  2229. * get name of split being written
  2230. */
  2231. char *get_out_split_path(base_path, disk_number)
  2232. char *base_path;
  2233. ulg disk_number;
  2234. {
  2235. char *split_path = NULL;
  2236. int base_len = 0;
  2237. int path_len = 0;
  2238. ulg num = disk_number + 1;
  2239. char ext[6];
  2240. #ifdef VMS
  2241. int vers_len; /* File version length. */
  2242. char *vers_ptr; /* File version string. */
  2243. #endif /* def VMS */
  2244. /*
  2245. * A split has extension z01, z02, ..., z99, z100, z101, ... z999
  2246. * We currently support up to .z99999
  2247. * WinZip will also read .100, .101, ... but AppNote 6.2.2 uses above
  2248. * so use that. Means on DOS can only have 100 splits.
  2249. */
  2250. if (num > 99999) {
  2251. ZIPERR(ZE_BIG, "More than 99999 splits needed");
  2252. }
  2253. sprintf(ext, "z%02lu", num);
  2254. /* create path for this split - zip.c checked for .zip extension */
  2255. base_len = strlen(base_path) - 3;
  2256. path_len = base_len + strlen(ext);
  2257. #ifdef VMS
  2258. /* On VMS, locate the file version, and adjust base_len accordingly.
  2259. Note that path_len is correct, as-is.
  2260. */
  2261. vers_ptr = vms_file_version( base_path);
  2262. vers_len = strlen( vers_ptr);
  2263. base_len -= vers_len;
  2264. #endif /* def VMS */
  2265. if ((split_path = malloc(path_len + 1)) == NULL) {
  2266. ZIPERR(ZE_MEM, "split path");
  2267. }
  2268. /* copy base_path except for end zip */
  2269. strcpy(split_path, base_path);
  2270. split_path[base_len] = '\0';
  2271. /* add extension */
  2272. strcat(split_path, ext);
  2273. #ifdef VMS
  2274. /* On VMS, append (preserve) the file version. */
  2275. strcat(split_path, vers_ptr);
  2276. #endif /* def VMS */
  2277. return split_path;
  2278. }
  2279. /* close_split
  2280. *
  2281. * close a split - assume that the paths needed for the splits are
  2282. * available.
  2283. */
  2284. int close_split(disk_number, tempfile, temp_name)
  2285. ulg disk_number;
  2286. FILE *tempfile;
  2287. char *temp_name;
  2288. {
  2289. char *split_path = NULL;
  2290. split_path = get_out_split_path(out_path, disk_number);
  2291. if (noisy_splits) {
  2292. zipmessage("\tClosing split ", split_path);
  2293. }
  2294. fclose(tempfile);
  2295. rename_split(temp_name, split_path);
  2296. set_filetype(split_path);
  2297. return ZE_OK;
  2298. }
  2299. /* bfwrite
  2300. Does the fwrite but also counts bytes and does splits */
  2301. size_t bfwrite(buffer, size, count, mode)
  2302. ZCONST void *buffer;
  2303. size_t size;
  2304. size_t count;
  2305. int mode;
  2306. {
  2307. size_t bytes_written = 0;
  2308. size_t r;
  2309. size_t b = size * count;
  2310. uzoff_t bytes_left_in_split = 0;
  2311. size_t bytes_to_write = b;
  2312. /* -------------------------------- */
  2313. /* local header */
  2314. if (mode == BFWRITE_LOCALHEADER) {
  2315. /* writing local header - reset entry data count */
  2316. bytes_this_entry = 0;
  2317. /* save start of local header so we can rewrite later */
  2318. current_local_file = y;
  2319. current_local_disk = current_disk;
  2320. current_local_offset = bytes_this_split;
  2321. }
  2322. if (split_size == 0)
  2323. bytes_left_in_split = bytes_to_write;
  2324. else
  2325. bytes_left_in_split = split_size - bytes_this_split;
  2326. if (bytes_to_write > bytes_left_in_split) {
  2327. if (mode == BFWRITE_HEADER ||
  2328. mode == BFWRITE_LOCALHEADER ||
  2329. mode == BFWRITE_CENTRALHEADER) {
  2330. /* if can't write entire header save for next split */
  2331. bytes_to_write = 0;
  2332. } else {
  2333. /* normal data so fill the split */
  2334. bytes_to_write = (size_t)bytes_left_in_split;
  2335. }
  2336. }
  2337. /* -------------------------------- */
  2338. /* central header */
  2339. if (mode == BFWRITE_CENTRALHEADER) {
  2340. /* set start disk for CD */
  2341. if (cd_start_disk == (ulg)-1) {
  2342. cd_start_disk = current_disk;
  2343. cd_start_offset = bytes_this_split;
  2344. }
  2345. cd_entries_this_disk++;
  2346. total_cd_entries++;
  2347. }
  2348. /* -------------------------------- */
  2349. if (bytes_to_write > 0) {
  2350. /* write out the bytes for this split */
  2351. r = fwrite(buffer, size, bytes_to_write, y);
  2352. bytes_written += r;
  2353. bytes_to_write = b - r;
  2354. bytes_this_split += r;
  2355. if (mode == BFWRITE_DATA)
  2356. /* if data descriptor do not include in count */
  2357. bytes_this_entry += r;
  2358. } else {
  2359. bytes_to_write = b;
  2360. }
  2361. if (bytes_to_write > 0) {
  2362. if (split_method) {
  2363. /* still bytes to write so close split and open next split */
  2364. bytes_prev_splits += bytes_this_split;
  2365. if (split_method == 1 && ferror(y)) {
  2366. /* if writing all splits to same place and have problem then bad */
  2367. ZIPERR(ZE_WRITE, "Could not write split");
  2368. }
  2369. if (split_method == 2 && ferror(y)) {
  2370. /* A split must be at least 64K except last .zip split */
  2371. if (bytes_this_split < 64 * (uzoff_t)0x400) {
  2372. ZIPERR(ZE_WRITE, "Not enough space to write split");
  2373. }
  2374. }
  2375. /* close this split */
  2376. if (split_method == 1 && current_local_disk == current_disk) {
  2377. /* keep split open so can update it */
  2378. current_local_tempname = tempzip;
  2379. } else {
  2380. /* close split */
  2381. close_split(current_disk, y, tempzip);
  2382. y = NULL;
  2383. free(tempzip);
  2384. tempzip = NULL;
  2385. }
  2386. cd_entries_this_disk = 0;
  2387. bytes_this_split = 0;
  2388. /* increment disk - disks are numbered 0, 1, 2, ... and
  2389. splits are 01, 02, ... */
  2390. current_disk++;
  2391. if (split_method == 2 && split_bell) {
  2392. /* bell when pause to ask for next split */
  2393. putc('\007', mesg);
  2394. fflush(mesg);
  2395. }
  2396. for (;;) {
  2397. /* if method 2 pause and allow changing path */
  2398. if (split_method == 2) {
  2399. if (ask_for_split_write_path(current_disk) == 0) {
  2400. ZIPERR(ZE_ABORT, "could not write split");
  2401. }
  2402. }
  2403. /* open next split */
  2404. #if defined(UNIX) && !defined(NO_MKSTEMP)
  2405. {
  2406. int yd;
  2407. int i;
  2408. /* use mkstemp to avoid race condition and compiler warning */
  2409. if (tempath != NULL)
  2410. {
  2411. /* if -b used to set temp file dir use that for split temp */
  2412. if ((tempzip = malloc(strlen(tempath) + 12)) == NULL) {
  2413. ZIPERR(ZE_MEM, "allocating temp filename");
  2414. }
  2415. strcpy(tempzip, tempath);
  2416. if (lastchar(tempzip) != '/')
  2417. strcat(tempzip, "/");
  2418. }
  2419. else
  2420. {
  2421. /* create path by stripping name and appending template */
  2422. if ((tempzip = malloc(strlen(zipfile) + 12)) == NULL) {
  2423. ZIPERR(ZE_MEM, "allocating temp filename");
  2424. }
  2425. strcpy(tempzip, zipfile);
  2426. for(i = strlen(tempzip); i > 0; i--) {
  2427. if (tempzip[i - 1] == '/')
  2428. break;
  2429. }
  2430. tempzip[i] = '\0';
  2431. }
  2432. strcat(tempzip, "ziXXXXXX");
  2433. if ((yd = mkstemp(tempzip)) == EOF) {
  2434. ZIPERR(ZE_TEMP, tempzip);
  2435. }
  2436. if ((y = fdopen(yd, FOPW_TMP)) == NULL) {
  2437. ZIPERR(ZE_TEMP, tempzip);
  2438. }
  2439. }
  2440. #else
  2441. if ((tempzip = tempname(zipfile)) == NULL) {
  2442. ZIPERR(ZE_MEM, "allocating temp filename");
  2443. }
  2444. if ((y = zfopen(tempzip, FOPW_TMP)) == NULL) {
  2445. ZIPERR(ZE_TEMP, tempzip);
  2446. }
  2447. #endif
  2448. r = fwrite((char *)buffer + bytes_written, 1, bytes_to_write, y);
  2449. bytes_written += r;
  2450. bytes_this_split += r;
  2451. if (!(mode == BFWRITE_HEADER ||
  2452. mode == BFWRITE_LOCALHEADER ||
  2453. mode == BFWRITE_CENTRALHEADER)) {
  2454. bytes_this_entry += r;
  2455. }
  2456. if (bytes_to_write > r) {
  2457. /* buffer bigger than split */
  2458. if (split_method == 2) {
  2459. /* let user choose another disk */
  2460. zipwarn("Not enough room on disk", "");
  2461. continue;
  2462. } else {
  2463. ZIPERR(ZE_WRITE, "Not enough room on disk");
  2464. }
  2465. }
  2466. if (mode == BFWRITE_LOCALHEADER ||
  2467. mode == BFWRITE_HEADER ||
  2468. mode == BFWRITE_CENTRALHEADER) {
  2469. if (split_method == 1 && current_local_file &&
  2470. current_local_disk != current_disk) {
  2471. /* We're opening a new split because the next header
  2472. did not fit on the last split. We need to now close
  2473. the last split and update the pointers for
  2474. the current split. */
  2475. close_split(current_local_disk, current_local_file,
  2476. current_local_tempname);
  2477. free(current_local_tempname);
  2478. }
  2479. current_local_tempname = tempzip;
  2480. current_local_file = y;
  2481. current_local_offset = 0;
  2482. current_local_disk = current_disk;
  2483. }
  2484. break;
  2485. }
  2486. }
  2487. else
  2488. {
  2489. /* likely have more than fits but no splits */
  2490. /* probably already have error "no space left on device" */
  2491. /* could let flush_outbuf() handle error but bfwrite() is called for
  2492. headers also */
  2493. if (ferror(y))
  2494. ziperr(ZE_WRITE, "write error on zip file");
  2495. }
  2496. }
  2497. /* display dots for archive instead of for each file */
  2498. if (display_globaldots) {
  2499. if (dot_size > 0) {
  2500. /* initial space */
  2501. if (dot_count == -1) {
  2502. #ifndef WINDLL
  2503. putc(' ', mesg);
  2504. fflush(mesg);
  2505. #else
  2506. fprintf(stdout,"%c",' ');
  2507. #endif
  2508. /* assume a header will be written first, so avoid 0 */
  2509. dot_count = 1;
  2510. }
  2511. /* skip incrementing dot count for small buffers like for headers */
  2512. if (size * count > 1000) {
  2513. dot_count++;
  2514. if (dot_size <= dot_count * (zoff_t)size * (zoff_t)count) dot_count = 0;
  2515. }
  2516. }
  2517. if (dot_size && !dot_count) {
  2518. dot_count++;
  2519. #ifndef WINDLL
  2520. putc('.', mesg);
  2521. fflush(mesg);
  2522. #else
  2523. fprintf(stdout,"%c",'.');
  2524. #endif
  2525. mesg_line_started = 1;
  2526. }
  2527. }
  2528. return bytes_written;
  2529. }
  2530. #ifdef UNICODE_SUPPORT
  2531. /*---------------------------------------------
  2532. * Unicode conversion functions
  2533. *
  2534. * Provided by Paul Kienitz
  2535. *
  2536. * Some modifications to work with Zip
  2537. *
  2538. *---------------------------------------------
  2539. */
  2540. /*
  2541. NOTES APPLICABLE TO ALL STRING FUNCTIONS:
  2542. All of the x_to_y functions take parameters for an output buffer and
  2543. its available length, and return an int. The value returned is the
  2544. length of the string that the input produces, which may be larger than
  2545. the provided buffer length. If the returned value is less than the
  2546. buffer length, then the contents of the buffer will be null-terminated;
  2547. otherwise, it will not be terminated and may be invalid, possibly
  2548. stopping in the middle of a multibyte sequence.
  2549. In all cases you may pass NULL as the buffer and/or 0 as the length, if
  2550. you just want to learn how much space the string is going to require.
  2551. The functions will return -1 if the input is invalid UTF-8 or cannot be
  2552. encoded as UTF-8.
  2553. */
  2554. /* utility functions for managing UTF-8 and UCS-4 strings */
  2555. /* utf8_char_bytes
  2556. *
  2557. * Returns the number of bytes used by the first character in a UTF-8
  2558. * string, or -1 if the UTF-8 is invalid or null.
  2559. */
  2560. local int utf8_char_bytes(utf8)
  2561. ZCONST char *utf8;
  2562. {
  2563. int t, r;
  2564. unsigned lead;
  2565. if (!utf8)
  2566. return -1; /* no input */
  2567. lead = (unsigned char) *utf8;
  2568. if (lead < 0x80)
  2569. r = 1; /* an ascii-7 character */
  2570. else if (lead < 0xC0)
  2571. return -1; /* error: trailing byte without lead byte */
  2572. else if (lead < 0xE0)
  2573. r = 2; /* an 11 bit character */
  2574. else if (lead < 0xF0)
  2575. r = 3; /* a 16 bit character */
  2576. else if (lead < 0xF8)
  2577. r = 4; /* a 21 bit character (the most currently used) */
  2578. else if (lead < 0xFC)
  2579. r = 5; /* a 26 bit character (shouldn't happen) */
  2580. else if (lead < 0xFE)
  2581. r = 6; /* a 31 bit character (shouldn't happen) */
  2582. else
  2583. return -1; /* error: invalid lead byte */
  2584. for (t = 1; t < r; t++)
  2585. if ((unsigned char) utf8[t] < 0x80 || (unsigned char) utf8[t] >= 0xC0)
  2586. return -1; /* error: not enough valid trailing bytes */
  2587. return r;
  2588. }
  2589. /* ucs4_char_from_utf8
  2590. *
  2591. * Given a reference to a pointer into a UTF-8 string, returns the next
  2592. * UCS-4 character and advances the pointer to the next character sequence.
  2593. * Returns ~0 and does not advance the pointer when input is ill-formed.
  2594. *
  2595. * Since the Unicode standard says 32-bit values won't be used (just
  2596. * up to the current 21-bit mappings) changed this to signed to allow -1 to
  2597. * be returned.
  2598. */
  2599. long ucs4_char_from_utf8(utf8)
  2600. ZCONST char **utf8;
  2601. {
  2602. ulg ret;
  2603. int t, bytes;
  2604. if (!utf8)
  2605. return -1; /* no input */
  2606. bytes = utf8_char_bytes(*utf8);
  2607. if (bytes <= 0)
  2608. return -1; /* invalid input */
  2609. if (bytes == 1)
  2610. ret = **utf8; /* ascii-7 */
  2611. else
  2612. ret = **utf8 & (0x7F >> bytes); /* lead byte of a multibyte sequence */
  2613. (*utf8)++;
  2614. for (t = 1; t < bytes; t++) /* consume trailing bytes */
  2615. ret = (ret << 6) | (*((*utf8)++) & 0x3F);
  2616. return (long) ret;
  2617. }
  2618. /* utf8_from_ucs4_char - Convert UCS char to UTF-8
  2619. *
  2620. * Returns the number of bytes put into utf8buf to represent ch, from 1 to 6,
  2621. * or -1 if ch is too large to represent. utf8buf must have room for 6 bytes.
  2622. */
  2623. local int utf8_from_ucs4_char(utf8buf, ch)
  2624. char *utf8buf;
  2625. ulg ch;
  2626. {
  2627. int trailing = 0;
  2628. int leadmask = 0x80;
  2629. int leadbits = 0x3F;
  2630. ulg tch = ch;
  2631. int ret;
  2632. if (ch > 0x7FFFFFFF)
  2633. return -1; /* UTF-8 can represent 31 bits */
  2634. if (ch < 0x7F)
  2635. {
  2636. *utf8buf++ = (char) ch; /* ascii-7 */
  2637. return 1;
  2638. }
  2639. do {
  2640. trailing++;
  2641. leadmask = (leadmask >> 1) | 0x80;
  2642. leadbits >>= 1;
  2643. tch >>= 6;
  2644. } while (tch & ~leadbits);
  2645. ret = trailing + 1;
  2646. /* produce lead byte */
  2647. *utf8buf++ = (char) (leadmask | (ch >> (6 * trailing)));
  2648. /* produce trailing bytes */
  2649. while (--trailing >= 0)
  2650. *utf8buf++ = (char) (0x80 | ((ch >> (6 * trailing)) & 0x3F));
  2651. return ret;
  2652. }
  2653. /*===================================================================*/
  2654. /* utf8_to_ucs4_string - convert UTF-8 string to UCS string
  2655. *
  2656. * Return UCS count. Now returns int so can return -1.
  2657. */
  2658. local int utf8_to_ucs4_string(utf8, ucs4buf, buflen)
  2659. ZCONST char *utf8;
  2660. ulg *ucs4buf;
  2661. int buflen;
  2662. {
  2663. int count = 0;
  2664. for (;;)
  2665. {
  2666. long ch = ucs4_char_from_utf8(&utf8);
  2667. if (ch == -1)
  2668. return -1;
  2669. else
  2670. {
  2671. if (ucs4buf && count < buflen)
  2672. ucs4buf[count] = ch;
  2673. if (ch == 0)
  2674. return count;
  2675. count++;
  2676. }
  2677. }
  2678. }
  2679. /* ucs4_string_to_utf8
  2680. *
  2681. *
  2682. */
  2683. local int ucs4_string_to_utf8(ucs4, utf8buf, buflen)
  2684. ZCONST ulg *ucs4;
  2685. char *utf8buf;
  2686. int buflen;
  2687. {
  2688. char mb[6];
  2689. int count = 0;
  2690. if (!ucs4)
  2691. return -1;
  2692. for (;;)
  2693. {
  2694. int mbl = utf8_from_ucs4_char(mb, *ucs4++);
  2695. int c;
  2696. if (mbl <= 0)
  2697. return -1;
  2698. /* We could optimize this a bit by passing utf8buf + count */
  2699. /* directly to utf8_from_ucs4_char when buflen >= count + 6... */
  2700. c = buflen - count;
  2701. if (mbl < c)
  2702. c = mbl;
  2703. if (utf8buf && count < buflen)
  2704. strncpy(utf8buf + count, mb, c);
  2705. if (mbl == 1 && !mb[0])
  2706. return count; /* terminating nul */
  2707. count += mbl;
  2708. }
  2709. }
  2710. #if 0 /* currently unused */
  2711. /* utf8_chars
  2712. *
  2713. * Wrapper: counts the actual unicode characters in a UTF-8 string.
  2714. */
  2715. local int utf8_chars(utf8)
  2716. ZCONST char *utf8;
  2717. {
  2718. return utf8_to_ucs4_string(utf8, NULL, 0);
  2719. }
  2720. #endif
  2721. /* --------------------------------------------------- */
  2722. /* Unicode Support
  2723. *
  2724. * These functions common for all Unicode ports.
  2725. *
  2726. * These functions should allocate and return strings that can be
  2727. * freed with free().
  2728. *
  2729. * 8/27/05 EG
  2730. *
  2731. * Use zwchar for wide char which is unsigned long
  2732. * in zip.h and 32 bits. This avoids problems with
  2733. * different sizes of wchar_t.
  2734. */
  2735. #ifdef WIN32
  2736. zwchar *wchar_to_wide_string(wchar_string)
  2737. wchar_t *wchar_string;
  2738. {
  2739. int i;
  2740. int wchar_len;
  2741. zwchar *wide_string;
  2742. wchar_len = wcslen(wchar_string);
  2743. if ((wide_string = malloc((wchar_len + 1) * sizeof(zwchar))) == NULL) {
  2744. ZIPERR(ZE_MEM, "wchar to wide conversion");
  2745. }
  2746. for (i = 0; i <= wchar_len; i++) {
  2747. wide_string[i] = wchar_string[i];
  2748. }
  2749. return wide_string;
  2750. }
  2751. /* is_ascii_stringw
  2752. * Checks if a wide string is all ascii
  2753. */
  2754. int is_ascii_stringw(wstring)
  2755. wchar_t *wstring;
  2756. {
  2757. wchar_t *pw;
  2758. wchar_t cw;
  2759. if (wstring == NULL)
  2760. return 0;
  2761. for (pw = wstring; (cw = *pw) != '\0'; pw++) {
  2762. if (cw > 0x7F) {
  2763. return 0;
  2764. }
  2765. }
  2766. return 1;
  2767. }
  2768. #endif
  2769. /* is_ascii_string
  2770. * Checks if a string is all ascii
  2771. */
  2772. int is_ascii_string(mbstring)
  2773. char *mbstring;
  2774. {
  2775. char *p;
  2776. uch c;
  2777. if (mbstring == NULL)
  2778. return 0;
  2779. for (p = mbstring; (c = (uch)*p) != '\0'; p++) {
  2780. if (c > 0x7F) {
  2781. return 0;
  2782. }
  2783. }
  2784. return 1;
  2785. }
  2786. /* local to UTF-8 */
  2787. char *local_to_utf8_string(local_string)
  2788. char *local_string;
  2789. {
  2790. zwchar *wide_string = local_to_wide_string(local_string);
  2791. char *utf8_string = wide_to_utf8_string(wide_string);
  2792. free(wide_string);
  2793. return utf8_string;
  2794. }
  2795. /* wide_char_to_escape_string
  2796. provides a string that represents a wide char not in local char set
  2797. An initial try at an algorithm. Suggestions welcome.
  2798. If not an ASCII char, probably need 2 bytes at least. So if
  2799. a 2-byte wide encode it as 4 hex digits with a leading #U.
  2800. Since the Unicode standard has been frozen, it looks like 3 bytes
  2801. should be enough for any large Unicode character. In these cases
  2802. prefix the string with #L.
  2803. So
  2804. #U1234
  2805. is a 2-byte wide character with bytes 0x12 and 0x34 while
  2806. #L123456
  2807. is a 3-byte wide with bytes 0x12, 0x34, and 0x56.
  2808. On Windows, wide that need two wide characters as a surrogate pair
  2809. to represent them need to be converted to a single number.
  2810. */
  2811. /* set this to the max bytes an escape can be */
  2812. #define MAX_ESCAPE_BYTES 8
  2813. char *wide_char_to_escape_string(wide_char)
  2814. zwchar wide_char;
  2815. {
  2816. int i;
  2817. zwchar w = wide_char;
  2818. uch b[9];
  2819. char e[7];
  2820. int len;
  2821. char *r;
  2822. /* fill byte array with zeros */
  2823. for (len = 0; len < sizeof(zwchar); len++) {
  2824. b[len] = 0;
  2825. }
  2826. /* get bytes in right to left order */
  2827. for (len = 0; w; len++) {
  2828. b[len] = (char)(w % 0x100);
  2829. w /= 0x100;
  2830. }
  2831. if ((r = malloc(MAX_ESCAPE_BYTES + 8)) == NULL) {
  2832. ZIPERR(ZE_MEM, "wide_char_to_escape_string");
  2833. }
  2834. strcpy(r, "#");
  2835. /* either 2 bytes or 4 bytes */
  2836. if (len < 3) {
  2837. len = 2;
  2838. strcat(r, "U");
  2839. } else {
  2840. len = 3;
  2841. strcat(r, "L");
  2842. }
  2843. for (i = len - 1; i >= 0; i--) {
  2844. sprintf(e, "%02x", b[i]);
  2845. strcat(r, e);
  2846. }
  2847. return r;
  2848. }
  2849. #if 0
  2850. /* returns the wide character represented by the escape string */
  2851. zwchar escape_string_to_wide(escape_string)
  2852. char *escape_string;
  2853. {
  2854. int i;
  2855. zwchar w;
  2856. char c;
  2857. char u;
  2858. int len;
  2859. char *e = escape_string;
  2860. if (e == NULL) {
  2861. return 0;
  2862. }
  2863. if (e[0] != '#') {
  2864. /* no leading # */
  2865. return 0;
  2866. }
  2867. len = strlen(e);
  2868. /* either #U1234 or #L123456 format */
  2869. if (len != 6 && len != 8) {
  2870. return 0;
  2871. }
  2872. w = 0;
  2873. if (e[1] == 'L') {
  2874. if (len != 8) {
  2875. return 0;
  2876. }
  2877. /* 3 bytes */
  2878. for (i = 2; i < 8; i++) {
  2879. c = e[i];
  2880. u = toupper(c);
  2881. if (u >= 'A' && u <= 'F') {
  2882. w = w * 0x10 + (zwchar)(u + 10 - 'A');
  2883. } else if (c >= '0' && c <= '9') {
  2884. w = w * 0x10 + (zwchar)(c - '0');
  2885. } else {
  2886. return 0;
  2887. }
  2888. }
  2889. } else if (e[1] == 'U') {
  2890. /* 2 bytes */
  2891. for (i = 2; i < 6; i++) {
  2892. c = e[i];
  2893. u = toupper(c);
  2894. if (u >= 'A' && u <= 'F') {
  2895. w = w * 0x10 + (zwchar)(u + 10 - 'A');
  2896. } else if (c >= '0' && c <= '9') {
  2897. w = w * 0x10 + (zwchar)(c - '0');
  2898. } else {
  2899. return 0;
  2900. }
  2901. }
  2902. }
  2903. return w;
  2904. }
  2905. #endif
  2906. char *local_to_escape_string(local_string)
  2907. char *local_string;
  2908. {
  2909. zwchar *wide_string = local_to_wide_string(local_string);
  2910. char *escape_string = wide_to_escape_string(wide_string);
  2911. free(wide_string);
  2912. return escape_string;
  2913. }
  2914. #ifdef WIN32
  2915. char *wchar_to_local_string(wstring)
  2916. wchar_t *wstring;
  2917. {
  2918. zwchar *wide_string = wchar_to_wide_string(wstring);
  2919. char *local_string = wide_to_local_string(wide_string);
  2920. free(wide_string);
  2921. return local_string;
  2922. }
  2923. #endif
  2924. #ifndef WIN32 /* The Win32 port uses a system-specific variant. */
  2925. /* convert wide character string to multi-byte character string */
  2926. char *wide_to_local_string(wide_string)
  2927. zwchar *wide_string;
  2928. {
  2929. int i;
  2930. wchar_t wc;
  2931. int b;
  2932. int state_dependent;
  2933. int wsize = 0;
  2934. int max_bytes = MB_CUR_MAX;
  2935. char buf[9];
  2936. char *buffer = NULL;
  2937. char *local_string = NULL;
  2938. for (wsize = 0; wide_string[wsize]; wsize++) ;
  2939. if (MAX_ESCAPE_BYTES > max_bytes)
  2940. max_bytes = MAX_ESCAPE_BYTES;
  2941. if ((buffer = (char *)malloc(wsize * max_bytes + 1)) == NULL) {
  2942. ZIPERR(ZE_MEM, "wide_to_local_string");
  2943. }
  2944. /* convert it */
  2945. buffer[0] = '\0';
  2946. /* set initial state if state-dependent encoding */
  2947. wc = (wchar_t)'a';
  2948. b = wctomb(NULL, wc);
  2949. if (b == 0)
  2950. state_dependent = 0;
  2951. else
  2952. state_dependent = 1;
  2953. for (i = 0; i < wsize; i++) {
  2954. if (sizeof(wchar_t) < 4 && wide_string[i] > 0xFFFF) {
  2955. /* wchar_t probably 2 bytes */
  2956. /* could do surrogates if state_dependent and wctomb can do */
  2957. wc = zwchar_to_wchar_t_default_char;
  2958. } else {
  2959. wc = (wchar_t)wide_string[i];
  2960. }
  2961. b = wctomb(buf, wc);
  2962. if (unicode_escape_all) {
  2963. if (b == 1 && (uch)buf[0] <= 0x7f) {
  2964. /* ASCII */
  2965. strncat(buffer, buf, b);
  2966. } else {
  2967. /* use escape for wide character */
  2968. char *e = wide_char_to_escape_string(wide_string[i]);
  2969. strcat(buffer, e);
  2970. free(e);
  2971. }
  2972. } else if (b > 0) {
  2973. /* multi-byte char */
  2974. strncat(buffer, buf, b);
  2975. } else {
  2976. /* no MB for this wide */
  2977. if (use_wide_to_mb_default) {
  2978. /* default character */
  2979. strcat(buffer, wide_to_mb_default_string);
  2980. } else {
  2981. /* use escape for wide character */
  2982. char *e = wide_char_to_escape_string(wide_string[i]);
  2983. strcat(buffer, e);
  2984. free(e);
  2985. }
  2986. }
  2987. }
  2988. if ((local_string = (char *)malloc(strlen(buffer) + 1)) == NULL) {
  2989. free(buffer);
  2990. ZIPERR(ZE_MEM, "wide_to_local_string");
  2991. }
  2992. strcpy(local_string, buffer);
  2993. free(buffer);
  2994. return local_string;
  2995. }
  2996. #endif /* !WIN32 */
  2997. /* convert wide character string to escaped string */
  2998. char *wide_to_escape_string(wide_string)
  2999. zwchar *wide_string;
  3000. {
  3001. int i;
  3002. int wsize = 0;
  3003. char buf[9];
  3004. char *buffer = NULL;
  3005. char *escape_string = NULL;
  3006. for (wsize = 0; wide_string[wsize]; wsize++) ;
  3007. if ((buffer = (char *)malloc(wsize * MAX_ESCAPE_BYTES + 1)) == NULL) {
  3008. ZIPERR(ZE_MEM, "wide_to_escape_string");
  3009. }
  3010. /* convert it */
  3011. buffer[0] = '\0';
  3012. for (i = 0; i < wsize; i++) {
  3013. if (wide_string[i] <= 0x7f && isprint((char)wide_string[i])) {
  3014. /* ASCII */
  3015. buf[0] = (char)wide_string[i];
  3016. buf[1] = '\0';
  3017. strcat(buffer, buf);
  3018. } else {
  3019. /* use escape for wide character */
  3020. char *e = wide_char_to_escape_string(wide_string[i]);
  3021. strcat(buffer, e);
  3022. free(e);
  3023. }
  3024. }
  3025. if ((escape_string = (char *)malloc(strlen(buffer) + 1)) == NULL) {
  3026. ZIPERR(ZE_MEM, "wide_to_escape_string");
  3027. }
  3028. strcpy(escape_string, buffer);
  3029. free(buffer);
  3030. return escape_string;
  3031. }
  3032. /* convert local string to display character set string */
  3033. char *local_to_display_string(local_string)
  3034. char *local_string;
  3035. {
  3036. char *temp_string;
  3037. char *display_string;
  3038. /* For Windows, OEM string should never be bigger than ANSI string, says
  3039. CharToOem description.
  3040. On UNIX, non-printable characters (0x00 - 0xFF) will be replaced by
  3041. "^x", so more space may be needed. Note that "^" itself is a valid
  3042. name character, so this leaves an ambiguity, but UnZip displays
  3043. names this way, too. (0x00 is not possible, I hope.)
  3044. For all other ports, just make a copy of local_string.
  3045. */
  3046. #ifdef UNIX
  3047. char *cp_dst; /* Character pointers used in the */
  3048. char *cp_src; /* copying/changing procedure. */
  3049. #endif
  3050. if ((temp_string = (char *)malloc(2 * strlen(local_string) + 1)) == NULL) {
  3051. ZIPERR(ZE_MEM, "local_to_display_string");
  3052. }
  3053. #ifdef WIN32
  3054. /* convert to OEM display character set */
  3055. local_to_oem_string(temp_string, local_string);
  3056. #else
  3057. # ifdef UNIX
  3058. /* Copy source string, expanding non-printable characters to "^x". */
  3059. cp_dst = temp_string;
  3060. cp_src = local_string;
  3061. while (*cp_src != '\0') {
  3062. if ((unsigned char)*cp_src < ' ') {
  3063. *cp_dst++ = '^';
  3064. *cp_dst++ = '@'+ *cp_src++;
  3065. }
  3066. else {
  3067. *cp_dst++ = *cp_src++;
  3068. }
  3069. }
  3070. *cp_dst = '\0';
  3071. # else /* not UNIX */
  3072. strcpy(temp_string, local_string);
  3073. # endif /* UNIX */
  3074. #endif
  3075. #ifdef EBCDIC
  3076. {
  3077. char *ebc;
  3078. if ((ebc = malloc(strlen(display_string) + 1)) == NULL) {
  3079. ZIPERR(ZE_MEM, "local_to_display_string");
  3080. }
  3081. strtoebc(ebc, display_string);
  3082. free(display_string);
  3083. display_string = ebc;
  3084. }
  3085. #endif
  3086. if ((display_string = (char *)malloc(strlen(temp_string) + 1)) == NULL) {
  3087. ZIPERR(ZE_MEM, "local_to_display_string");
  3088. }
  3089. strcpy(display_string, temp_string);
  3090. free(temp_string);
  3091. return display_string;
  3092. }
  3093. /* UTF-8 to local */
  3094. char *utf8_to_local_string(utf8_string)
  3095. char *utf8_string;
  3096. {
  3097. zwchar *wide_string = utf8_to_wide_string(utf8_string);
  3098. char *loc = wide_to_local_string(wide_string);
  3099. if (wide_string)
  3100. free(wide_string);
  3101. return loc;
  3102. }
  3103. /* UTF-8 to local */
  3104. char *utf8_to_escape_string(utf8_string)
  3105. char *utf8_string;
  3106. {
  3107. zwchar *wide_string = utf8_to_wide_string(utf8_string);
  3108. char *escape_string = wide_to_escape_string(wide_string);
  3109. free(wide_string);
  3110. return escape_string;
  3111. }
  3112. #ifndef WIN32 /* The Win32 port uses a system-specific variant. */
  3113. /* convert multi-byte character string to wide character string */
  3114. zwchar *local_to_wide_string(local_string)
  3115. char *local_string;
  3116. {
  3117. int wsize;
  3118. wchar_t *wc_string;
  3119. zwchar *wide_string;
  3120. /* for now try to convert as string - fails if a bad char in string */
  3121. wsize = mbstowcs(NULL, local_string, MB_CUR_MAX );
  3122. if (wsize == (size_t)-1) {
  3123. /* could not convert */
  3124. return NULL;
  3125. }
  3126. /* convert it */
  3127. if ((wc_string = (wchar_t *)malloc((wsize + 1) * sizeof(wchar_t))) == NULL) {
  3128. ZIPERR(ZE_MEM, "local_to_wide_string");
  3129. }
  3130. wsize = mbstowcs(wc_string, local_string, strlen(local_string) + 1);
  3131. wc_string[wsize] = (wchar_t) 0;
  3132. /* in case wchar_t is not zwchar */
  3133. if ((wide_string = (zwchar *)malloc((wsize + 1) * sizeof(zwchar))) == NULL) {
  3134. ZIPERR(ZE_MEM, "local_to_wide_string");
  3135. }
  3136. for (wsize = 0; (wide_string[wsize] = (zwchar)wc_string[wsize]); wsize++) ;
  3137. wide_string[wsize] = (zwchar)0;
  3138. free(wc_string);
  3139. return wide_string;
  3140. }
  3141. #endif /* !WIN32 */
  3142. #if 0
  3143. /* All wchar functions are only used by Windows and are
  3144. now in win32zip.c so that the Windows functions can
  3145. be used and multiple character wide characters can
  3146. be handled easily. */
  3147. # ifndef WIN32
  3148. char *wchar_to_utf8_string(wstring)
  3149. wchar_t *wstring;
  3150. {
  3151. zwchar *wide_string = wchar_to_wide_string(wstring);
  3152. char *local_string = wide_to_utf8_string(wide_string);
  3153. free(wide_string);
  3154. return local_string;
  3155. }
  3156. # endif
  3157. #endif
  3158. /* convert wide string to UTF-8 */
  3159. char *wide_to_utf8_string(wide_string)
  3160. zwchar *wide_string;
  3161. {
  3162. int mbcount;
  3163. char *utf8_string;
  3164. /* get size of utf8 string */
  3165. mbcount = ucs4_string_to_utf8(wide_string, NULL, 0);
  3166. if (mbcount == -1)
  3167. return NULL;
  3168. if ((utf8_string = (char *) malloc(mbcount + 1)) == NULL) {
  3169. ZIPERR(ZE_MEM, "wide_to_utf8_string");
  3170. }
  3171. mbcount = ucs4_string_to_utf8(wide_string, utf8_string, mbcount + 1);
  3172. if (mbcount == -1)
  3173. return NULL;
  3174. return utf8_string;
  3175. }
  3176. /* convert UTF-8 string to wide string */
  3177. zwchar *utf8_to_wide_string(utf8_string)
  3178. char *utf8_string;
  3179. {
  3180. int wcount;
  3181. zwchar *wide_string;
  3182. wcount = utf8_to_ucs4_string(utf8_string, NULL, 0);
  3183. if (wcount == -1)
  3184. return NULL;
  3185. if ((wide_string = (zwchar *) malloc((wcount + 2) * sizeof(zwchar))) == NULL) {
  3186. ZIPERR(ZE_MEM, "utf8_to_wide_string");
  3187. }
  3188. wcount = utf8_to_ucs4_string(utf8_string, wide_string, wcount + 1);
  3189. return wide_string;
  3190. }
  3191. #endif /* UNICODE_SUPPORT */
  3192. /*---------------------------------------------------------------
  3193. * Long option support
  3194. * 8/23/2003
  3195. *
  3196. * Defines function get_option() to get and process the command
  3197. * line options and arguments from argv[]. The caller calls
  3198. * get_option() in a loop to get either one option and possible
  3199. * value or a non-option argument each loop.
  3200. *
  3201. * This version does not include argument file support and can
  3202. * work directly on argv. The argument file code complicates things and
  3203. * it seemed best to leave it out for now. If argument file support (reading
  3204. * in command line arguments stored in a file and inserting into
  3205. * command line where @filename is found) is added later the arguments
  3206. * can change and a freeable copy of argv will be needed and can be
  3207. * created using copy_args in the left out code.
  3208. *
  3209. * Supports short and long options as defined in the array options[]
  3210. * in zip.c, multiple short options in an argument (like -jlv), long
  3211. * option abbreviation (like --te for --temp-file if --te unique),
  3212. * short and long option values (like -b filename or --temp-file filename
  3213. * or --temp-file=filename), optional and required values, option negation
  3214. * by trailing - (like -S- to not include hidden and system files in MSDOS),
  3215. * value lists (like -x a b c), argument permuting (returning all options
  3216. * and values before any non-option arguments), and argument files (where any
  3217. * non-option non-value argument in form @path gets substituted with the
  3218. * white space separated arguments in the text file at path). In this
  3219. * version argument file support has been removed to simplify development but
  3220. * may be added later.
  3221. *
  3222. * E. Gordon
  3223. */
  3224. /* message output - char casts are needed to handle constants */
  3225. #define oWARN(message) zipwarn((char *) message, "")
  3226. #define oERR(err,message) ZIPERR(err, (char *) message)
  3227. /* Although the below provides some support for multibyte characters
  3228. the proper thing to do may be to use wide characters and support
  3229. Unicode. May get to it soon. EG
  3230. */
  3231. /* For now stay with muti-byte characters. May support wide characters
  3232. in Zip 3.1.
  3233. */
  3234. /* multibyte character set support
  3235. Multibyte characters use typically two or more sequential bytes
  3236. to represent additional characters than can fit in a single byte
  3237. character set. The code used here is based on the ANSI mblen function. */
  3238. #ifdef MULTIBYTE_GETOPTNS
  3239. int mb_clen(ptr)
  3240. ZCONST char *ptr;
  3241. {
  3242. /* return the number of bytes that the char pointed to is. Return 1 if
  3243. null character or error like not start of valid multibyte character. */
  3244. int cl;
  3245. cl = mblen(ptr, MB_CUR_MAX);
  3246. return (cl > 0) ? cl : 1;
  3247. }
  3248. #endif
  3249. /* moved to zip.h */
  3250. #if 0
  3251. #ifdef UNICODE_SUPPORT
  3252. # define MB_CLEN(ptr) (1)
  3253. # define MB_NEXTCHAR(ptr) ((ptr)++)
  3254. # ifdef MULTIBYTE_GETOPTNS
  3255. # undef MULTIBYTE_GETOPTNS
  3256. # endif
  3257. #else
  3258. # ifdef _MBCS
  3259. # ifndef MULTIBYTE_GETOPTNS
  3260. # define MULTIBYTE_GETOPTNS
  3261. # endif
  3262. # endif
  3263. /* multibyte character set support
  3264. Multibyte characters use typically two or more sequential bytes
  3265. to represent additional characters than can fit in a single byte
  3266. character set. The code used here is based on the ANSI mblen function. */
  3267. # ifdef MULTIBYTE_GETOPTNS
  3268. local int mb_clen OF((ZCONST char *)); /* declare proto first */
  3269. local int mb_clen(ptr)
  3270. ZCONST char *ptr;
  3271. {
  3272. /* return the number of bytes that the char pointed to is. Return 1 if
  3273. null character or error like not start of valid multibyte character. */
  3274. int cl;
  3275. cl = mblen(ptr, MB_CUR_MAX);
  3276. return (cl > 0) ? cl : 1;
  3277. }
  3278. # define MB_CLEN(ptr) mb_clen(ptr)
  3279. # define MB_NEXTCHAR(ptr) ((ptr) += MB_CLEN(ptr))
  3280. # else
  3281. # define MB_CLEN(ptr) (1)
  3282. # define MB_NEXTCHAR(ptr) ((ptr)++)
  3283. # endif
  3284. #endif
  3285. #endif
  3286. /* constants */
  3287. /* function get_args_from_arg_file() can return this in depth parameter */
  3288. #define ARG_FILE_ERR -1
  3289. /* internal settings for optchar */
  3290. #define SKIP_VALUE_ARG -1
  3291. #define THIS_ARG_DONE -2
  3292. #define START_VALUE_LIST -3
  3293. #define IN_VALUE_LIST -4
  3294. #define NON_OPTION_ARG -5
  3295. #define STOP_VALUE_LIST -6
  3296. /* 7/25/04 EG */
  3297. #define READ_REST_ARGS_VERBATIM -7
  3298. /* global veriables */
  3299. int enable_permute = 1; /* yes - return options first */
  3300. /* 7/25/04 EG */
  3301. int doubledash_ends_options = 1; /* when -- what follows are not options */
  3302. /* buffer for error messages (this sizing is a guess but must hold 2 paths) */
  3303. #define OPTIONERR_BUF_SIZE (FNMAX * 2 + 4000)
  3304. local char Far optionerrbuf[OPTIONERR_BUF_SIZE + 1];
  3305. /* error messages */
  3306. static ZCONST char Far op_not_neg_err[] = "option %s not negatable";
  3307. static ZCONST char Far op_req_val_err[] = "option %s requires a value";
  3308. static ZCONST char Far op_no_allow_val_err[] = "option %s does not allow a value";
  3309. static ZCONST char Far sh_op_not_sup_err[] = "short option '%c' not supported";
  3310. static ZCONST char Far oco_req_val_err[] = "option %s requires one character value";
  3311. static ZCONST char Far oco_no_mbc_err[] = "option %s does not support multibyte values";
  3312. static ZCONST char Far num_req_val_err[] = "option %s requires number value";
  3313. static ZCONST char Far long_op_ambig_err[] = "long option '%s' ambiguous";
  3314. static ZCONST char Far long_op_not_sup_err[] = "long option '%s' not supported";
  3315. static ZCONST char Far no_arg_files_err[] = "argument files not enabled\n";
  3316. /* below removed as only used for processing argument files */
  3317. /* get_nextarg */
  3318. /* get_args_from_string */
  3319. /* insert_args */
  3320. /* get_args_from_arg_file */
  3321. /* copy error, option name, and option description if any to buf */
  3322. local int optionerr(buf, err, optind, islong)
  3323. char *buf;
  3324. ZCONST char *err;
  3325. int optind;
  3326. int islong;
  3327. {
  3328. char optname[50];
  3329. if (options[optind].name && options[optind].name[0] != '\0') {
  3330. if (islong)
  3331. sprintf(optname, "'%s' (%s)", options[optind].longopt, options[optind].name);
  3332. else
  3333. sprintf(optname, "'%s' (%s)", options[optind].shortopt, options[optind].name);
  3334. } else {
  3335. if (islong)
  3336. sprintf(optname, "'%s'", options[optind].longopt);
  3337. else
  3338. sprintf(optname, "'%s'", options[optind].shortopt);
  3339. }
  3340. sprintf(buf, err, optname);
  3341. return 0;
  3342. }
  3343. /* copy_args
  3344. *
  3345. * Copy arguments in args, allocating storage with malloc.
  3346. * Copies until a NULL argument is found or until max_args args
  3347. * including args[0] are copied. Set max_args to 0 to copy
  3348. * until NULL. Always terminates returned args[] with NULL arg.
  3349. *
  3350. * Any argument in the returned args can be freed with free(). Any
  3351. * freed argument should be replaced with either another string
  3352. * allocated with malloc or by NULL if last argument so that free_args
  3353. * will properly work.
  3354. */
  3355. char **copy_args(args, max_args)
  3356. char **args;
  3357. int max_args;
  3358. {
  3359. int j;
  3360. char **new_args;
  3361. if (args == NULL) {
  3362. return NULL;
  3363. }
  3364. /* count args */
  3365. for (j = 0; args[j] && (max_args == 0 || j < max_args); j++) ;
  3366. if ((new_args = (char **) malloc((j + 1) * sizeof(char *))) == NULL) {
  3367. oERR(ZE_MEM, "ca");
  3368. }
  3369. for (j = 0; args[j] && (max_args == 0 || j < max_args); j++) {
  3370. if (args[j] == NULL) {
  3371. /* null argument is end of args */
  3372. new_args[j] = NULL;
  3373. break;
  3374. }
  3375. if ((new_args[j] = malloc(strlen(args[j]) + 1)) == NULL) {
  3376. free_args(new_args);
  3377. oERR(ZE_MEM, "ca");
  3378. }
  3379. strcpy(new_args[j], args[j]);
  3380. }
  3381. new_args[j] = NULL;
  3382. return new_args;
  3383. }
  3384. /* free args - free args created with one of these functions */
  3385. int free_args(args)
  3386. char **args;
  3387. {
  3388. int i;
  3389. if (args == NULL) {
  3390. return 0;
  3391. }
  3392. for (i = 0; args[i]; i++) {
  3393. free(args[i]);
  3394. }
  3395. free(args);
  3396. return i;
  3397. }
  3398. /* insert_arg
  3399. *
  3400. * Insert the argument arg into the array args before argument at_arg.
  3401. * Return the new count of arguments (argc).
  3402. *
  3403. * If free_args is true, this function frees the old args array
  3404. * (but not the component strings). DO NOT set free_args on original
  3405. * argv but only on args allocated with malloc.
  3406. */
  3407. int insert_arg(pargs, arg, at_arg, free_args)
  3408. char ***pargs;
  3409. ZCONST char *arg;
  3410. int at_arg;
  3411. int free_args;
  3412. {
  3413. char *newarg = NULL;
  3414. char **args;
  3415. char **newargs = NULL;
  3416. int argnum;
  3417. int newargnum;
  3418. int argcnt;
  3419. int newargcnt;
  3420. if (pargs == NULL) {
  3421. return 0;
  3422. }
  3423. args = *pargs;
  3424. /* count args */
  3425. if (args == NULL) {
  3426. argcnt = 0;
  3427. } else {
  3428. for (argcnt = 0; args[argcnt]; argcnt++) ;
  3429. }
  3430. if (arg == NULL) {
  3431. /* done */
  3432. return argcnt;
  3433. }
  3434. newargcnt = argcnt + 1;
  3435. /* get storage for new args */
  3436. if ((newargs = (char **) malloc((newargcnt + 1) * sizeof(char *))) == NULL) {
  3437. oERR(ZE_MEM, "ia");
  3438. }
  3439. /* copy argument pointers from args to position at_arg, copy arg, then rest args */
  3440. argnum = 0;
  3441. newargnum = 0;
  3442. if (args) {
  3443. for (; args[argnum] && argnum < at_arg; argnum++) {
  3444. newargs[newargnum++] = args[argnum];
  3445. }
  3446. }
  3447. /* copy new arg */
  3448. if ((newarg = (char *) malloc(strlen(arg) + 1)) == NULL) {
  3449. oERR(ZE_MEM, "ia");
  3450. }
  3451. strcpy(newarg, arg);
  3452. newargs[newargnum++] = newarg;
  3453. if (args) {
  3454. for ( ; args[argnum]; argnum++) {
  3455. newargs[newargnum++] = args[argnum];
  3456. }
  3457. }
  3458. newargs[newargnum] = NULL;
  3459. /* free old args array but not component strings - this assumes that
  3460. args was allocated with malloc as copy_args does. DO NOT DO THIS
  3461. on the original argv.
  3462. */
  3463. if (free_args)
  3464. free(args);
  3465. *pargs = newargs;
  3466. return newargnum;
  3467. }
  3468. /* ------------------------------------- */
  3469. /* get_shortopt
  3470. *
  3471. * Get next short option from arg. The state is stored in argnum, optchar, and
  3472. * option_num so no static storage is used. Returns the option_ID.
  3473. *
  3474. * parameters:
  3475. * args - argv array of arguments
  3476. * argnum - index of current arg in args
  3477. * optchar - pointer to index of next char to process. Can be 0 or
  3478. * const defined at top of this file like THIS_ARG_DONE
  3479. * negated - on return pointer to int set to 1 if option negated or 0 otherwise
  3480. * value - on return pointer to string set to value of option if any or NULL
  3481. * if none. If value is returned then the caller should free()
  3482. * it when not needed anymore.
  3483. * option_num - pointer to index in options[] of returned option or
  3484. * o_NO_OPTION_MATCH if none. Do not change as used by
  3485. * value lists.
  3486. * depth - recursion depth (0 at top level, 1 or more in arg files)
  3487. */
  3488. local unsigned long get_shortopt(args, argnum, optchar, negated, value,
  3489. option_num, depth)
  3490. char **args;
  3491. int argnum;
  3492. int *optchar;
  3493. int *negated;
  3494. char **value;
  3495. int *option_num;
  3496. int depth;
  3497. {
  3498. char *shortopt;
  3499. int clen;
  3500. char *nextchar;
  3501. char *s;
  3502. char *start;
  3503. int op;
  3504. char *arg;
  3505. int match = -1;
  3506. /* get arg */
  3507. arg = args[argnum];
  3508. /* current char in arg */
  3509. nextchar = arg + (*optchar);
  3510. clen = MB_CLEN(nextchar);
  3511. /* next char in arg */
  3512. (*optchar) += clen;
  3513. /* get first char of short option */
  3514. shortopt = arg + (*optchar);
  3515. /* no value */
  3516. *value = NULL;
  3517. if (*shortopt == '\0') {
  3518. /* no more options in arg */
  3519. *optchar = 0;
  3520. *option_num = o_NO_OPTION_MATCH;
  3521. return 0;
  3522. }
  3523. /* look for match in options */
  3524. clen = MB_CLEN(shortopt);
  3525. for (op = 0; options[op].option_ID; op++) {
  3526. s = options[op].shortopt;
  3527. if (s && s[0] == shortopt[0]) {
  3528. if (s[1] == '\0' && clen == 1) {
  3529. /* single char match */
  3530. match = op;
  3531. } else {
  3532. /* 2 wide short opt. Could support more chars but should use long opts instead */
  3533. if (s[1] == shortopt[1]) {
  3534. /* match 2 char short opt or 2 byte char */
  3535. match = op;
  3536. if (clen == 1) (*optchar)++;
  3537. break;
  3538. }
  3539. }
  3540. }
  3541. }
  3542. if (match > -1) {
  3543. /* match */
  3544. clen = MB_CLEN(shortopt);
  3545. nextchar = arg + (*optchar) + clen;
  3546. /* check for trailing dash negating option */
  3547. if (*nextchar == '-') {
  3548. /* negated */
  3549. if (options[match].negatable == o_NOT_NEGATABLE) {
  3550. if (options[match].value_type == o_NO_VALUE) {
  3551. optionerr(optionerrbuf, op_not_neg_err, match, 0);
  3552. if (depth > 0) {
  3553. /* unwind */
  3554. oWARN(optionerrbuf);
  3555. return o_ARG_FILE_ERR;
  3556. } else {
  3557. oERR(ZE_PARMS, optionerrbuf);
  3558. }
  3559. }
  3560. } else {
  3561. *negated = 1;
  3562. /* set up to skip negating dash */
  3563. (*optchar) += clen;
  3564. clen = 1;
  3565. }
  3566. }
  3567. /* value */
  3568. clen = MB_CLEN(arg + (*optchar));
  3569. /* optional value, one char value, and number value must follow option */
  3570. if (options[match].value_type == o_ONE_CHAR_VALUE) {
  3571. /* one char value */
  3572. if (arg[(*optchar) + clen]) {
  3573. /* has value */
  3574. if (MB_CLEN(arg + (*optchar) + clen) > 1) {
  3575. /* multibyte value not allowed for now */
  3576. optionerr(optionerrbuf, oco_no_mbc_err, match, 0);
  3577. if (depth > 0) {
  3578. /* unwind */
  3579. oWARN(optionerrbuf);
  3580. return o_ARG_FILE_ERR;
  3581. } else {
  3582. oERR(ZE_PARMS, optionerrbuf);
  3583. }
  3584. }
  3585. if ((*value = (char *) malloc(2)) == NULL) {
  3586. oERR(ZE_MEM, "gso");
  3587. }
  3588. (*value)[0] = *(arg + (*optchar) + clen);
  3589. (*value)[1] = '\0';
  3590. *optchar += clen;
  3591. clen = 1;
  3592. } else {
  3593. /* one char values require a value */
  3594. optionerr(optionerrbuf, oco_req_val_err, match, 0);
  3595. if (depth > 0) {
  3596. oWARN(optionerrbuf);
  3597. return o_ARG_FILE_ERR;
  3598. } else {
  3599. oERR(ZE_PARMS, optionerrbuf);
  3600. }
  3601. }
  3602. } else if (options[match].value_type == o_NUMBER_VALUE) {
  3603. /* read chars until end of number */
  3604. start = arg + (*optchar) + clen;
  3605. if (*start == '+' || *start == '-') {
  3606. start++;
  3607. }
  3608. s = start;
  3609. for (; isdigit(*s); MB_NEXTCHAR(s)) ;
  3610. if (s == start) {
  3611. /* no digits */
  3612. optionerr(optionerrbuf, num_req_val_err, match, 0);
  3613. if (depth > 0) {
  3614. oWARN(optionerrbuf);
  3615. return o_ARG_FILE_ERR;
  3616. } else {
  3617. oERR(ZE_PARMS, optionerrbuf);
  3618. }
  3619. }
  3620. start = arg + (*optchar) + clen;
  3621. if ((*value = (char *) malloc((int)(s - start) + 1)) == NULL) {
  3622. oERR(ZE_MEM, "gso");
  3623. }
  3624. *optchar += (int)(s - start);
  3625. strncpy(*value, start, (int)(s - start));
  3626. (*value)[(int)(s - start)] = '\0';
  3627. clen = MB_CLEN(s);
  3628. } else if (options[match].value_type == o_OPTIONAL_VALUE) {
  3629. /* optional value */
  3630. /* This seemed inconsistent so now if no value attached to argument look
  3631. to the next argument if that argument is not an option for option
  3632. value - 11/12/04 EG */
  3633. if (arg[(*optchar) + clen]) {
  3634. /* has value */
  3635. /* add support for optional = - 2/6/05 EG */
  3636. if (arg[(*optchar) + clen] == '=') {
  3637. /* skip = */
  3638. clen++;
  3639. }
  3640. if (arg[(*optchar) + clen]) {
  3641. if ((*value = (char *)malloc(strlen(arg + (*optchar) + clen) + 1))
  3642. == NULL) {
  3643. oERR(ZE_MEM, "gso");
  3644. }
  3645. strcpy(*value, arg + (*optchar) + clen);
  3646. }
  3647. *optchar = THIS_ARG_DONE;
  3648. } else if (args[argnum + 1] && args[argnum + 1][0] != '-') {
  3649. /* use next arg for value */
  3650. if ((*value = (char *)malloc(strlen(args[argnum + 1]) + 1)) == NULL) {
  3651. oERR(ZE_MEM, "gso");
  3652. }
  3653. /* using next arg as value */
  3654. strcpy(*value, args[argnum + 1]);
  3655. *optchar = SKIP_VALUE_ARG;
  3656. }
  3657. } else if (options[match].value_type == o_REQUIRED_VALUE ||
  3658. options[match].value_type == o_VALUE_LIST) {
  3659. /* see if follows option */
  3660. if (arg[(*optchar) + clen]) {
  3661. /* has value following option as -ovalue */
  3662. /* add support for optional = - 6/5/05 EG */
  3663. if (arg[(*optchar) + clen] == '=') {
  3664. /* skip = */
  3665. clen++;
  3666. }
  3667. if ((*value = (char *)malloc(strlen(arg + (*optchar) + clen) + 1))
  3668. == NULL) {
  3669. oERR(ZE_MEM, "gso");
  3670. }
  3671. strcpy(*value, arg + (*optchar) + clen);
  3672. *optchar = THIS_ARG_DONE;
  3673. } else {
  3674. /* use next arg for value */
  3675. if (args[argnum + 1]) {
  3676. if ((*value = (char *)malloc(strlen(args[argnum + 1]) + 1)) == NULL) {
  3677. oERR(ZE_MEM, "gso");
  3678. }
  3679. strcpy(*value, args[argnum + 1]);
  3680. if (options[match].value_type == o_VALUE_LIST) {
  3681. *optchar = START_VALUE_LIST;
  3682. } else {
  3683. *optchar = SKIP_VALUE_ARG;
  3684. }
  3685. } else {
  3686. /* no value found */
  3687. optionerr(optionerrbuf, op_req_val_err, match, 0);
  3688. if (depth > 0) {
  3689. oWARN(optionerrbuf);
  3690. return o_ARG_FILE_ERR;
  3691. } else {
  3692. oERR(ZE_PARMS, optionerrbuf);
  3693. }
  3694. }
  3695. }
  3696. }
  3697. *option_num = match;
  3698. return options[match].option_ID;
  3699. }
  3700. sprintf(optionerrbuf, sh_op_not_sup_err, *shortopt);
  3701. if (depth > 0) {
  3702. /* unwind */
  3703. oWARN(optionerrbuf);
  3704. return o_ARG_FILE_ERR;
  3705. } else {
  3706. oERR(ZE_PARMS, optionerrbuf);
  3707. }
  3708. return 0;
  3709. }
  3710. /* get_longopt
  3711. *
  3712. * Get the long option in args array at argnum.
  3713. * Parameters same as for get_shortopt.
  3714. */
  3715. local unsigned long get_longopt(args, argnum, optchar, negated, value,
  3716. option_num, depth)
  3717. char **args;
  3718. int argnum;
  3719. int *optchar;
  3720. int *negated;
  3721. char **value;
  3722. int *option_num;
  3723. int depth;
  3724. {
  3725. char *longopt;
  3726. char *lastchr;
  3727. char *valuestart;
  3728. int op;
  3729. char *arg;
  3730. int match = -1;
  3731. *value = NULL;
  3732. if (args == NULL) {
  3733. *option_num = o_NO_OPTION_MATCH;
  3734. return 0;
  3735. }
  3736. if (args[argnum] == NULL) {
  3737. *option_num = o_NO_OPTION_MATCH;
  3738. return 0;
  3739. }
  3740. /* copy arg so can chop end if value */
  3741. if ((arg = (char *)malloc(strlen(args[argnum]) + 1)) == NULL) {
  3742. oERR(ZE_MEM, "glo");
  3743. }
  3744. strcpy(arg, args[argnum]);
  3745. /* get option */
  3746. longopt = arg + 2;
  3747. /* no value */
  3748. *value = NULL;
  3749. /* find = */
  3750. for (lastchr = longopt, valuestart = longopt;
  3751. *valuestart && *valuestart != '=';
  3752. lastchr = valuestart, MB_NEXTCHAR(valuestart)) ;
  3753. if (*valuestart) {
  3754. /* found =value */
  3755. *valuestart = '\0';
  3756. valuestart++;
  3757. } else {
  3758. valuestart = NULL;
  3759. }
  3760. if (*lastchr == '-') {
  3761. /* option negated */
  3762. *negated = 1;
  3763. *lastchr = '\0';
  3764. } else {
  3765. *negated = 0;
  3766. }
  3767. /* look for long option match */
  3768. for (op = 0; options[op].option_ID; op++) {
  3769. if (options[op].longopt && strcmp(options[op].longopt, longopt) == 0) {
  3770. /* exact match */
  3771. match = op;
  3772. break;
  3773. }
  3774. if (options[op].longopt && strncmp(options[op].longopt, longopt, strlen(longopt)) == 0) {
  3775. if (match > -1) {
  3776. sprintf(optionerrbuf, long_op_ambig_err, longopt);
  3777. free(arg);
  3778. if (depth > 0) {
  3779. /* unwind */
  3780. oWARN(optionerrbuf);
  3781. return o_ARG_FILE_ERR;
  3782. } else {
  3783. oERR(ZE_PARMS, optionerrbuf);
  3784. }
  3785. }
  3786. match = op;
  3787. }
  3788. }
  3789. if (match == -1) {
  3790. sprintf(optionerrbuf, long_op_not_sup_err, longopt);
  3791. free(arg);
  3792. if (depth > 0) {
  3793. oWARN(optionerrbuf);
  3794. return o_ARG_FILE_ERR;
  3795. } else {
  3796. oERR(ZE_PARMS, optionerrbuf);
  3797. }
  3798. }
  3799. /* one long option an arg */
  3800. *optchar = THIS_ARG_DONE;
  3801. /* if negated then see if allowed */
  3802. if (*negated && options[match].negatable == o_NOT_NEGATABLE) {
  3803. optionerr(optionerrbuf, op_not_neg_err, match, 1);
  3804. free(arg);
  3805. if (depth > 0) {
  3806. /* unwind */
  3807. oWARN(optionerrbuf);
  3808. return o_ARG_FILE_ERR;
  3809. } else {
  3810. oERR(ZE_PARMS, optionerrbuf);
  3811. }
  3812. }
  3813. /* get value */
  3814. if (options[match].value_type == o_OPTIONAL_VALUE) {
  3815. /* optional value in form option=value */
  3816. if (valuestart) {
  3817. /* option=value */
  3818. if ((*value = (char *)malloc(strlen(valuestart) + 1)) == NULL) {
  3819. free(arg);
  3820. oERR(ZE_MEM, "glo");
  3821. }
  3822. strcpy(*value, valuestart);
  3823. }
  3824. } else if (options[match].value_type == o_REQUIRED_VALUE ||
  3825. options[match].value_type == o_NUMBER_VALUE ||
  3826. options[match].value_type == o_ONE_CHAR_VALUE ||
  3827. options[match].value_type == o_VALUE_LIST) {
  3828. /* handle long option one char and number value as required value */
  3829. if (valuestart) {
  3830. /* option=value */
  3831. if ((*value = (char *)malloc(strlen(valuestart) + 1)) == NULL) {
  3832. free(arg);
  3833. oERR(ZE_MEM, "glo");
  3834. }
  3835. strcpy(*value, valuestart);
  3836. } else {
  3837. /* use next arg */
  3838. if (args[argnum + 1]) {
  3839. if ((*value = (char *)malloc(strlen(args[argnum + 1]) + 1)) == NULL) {
  3840. free(arg);
  3841. oERR(ZE_MEM, "glo");
  3842. }
  3843. /* using next arg as value */
  3844. strcpy(*value, args[argnum + 1]);
  3845. if (options[match].value_type == o_VALUE_LIST) {
  3846. *optchar = START_VALUE_LIST;
  3847. } else {
  3848. *optchar = SKIP_VALUE_ARG;
  3849. }
  3850. } else {
  3851. /* no value found */
  3852. optionerr(optionerrbuf, op_req_val_err, match, 1);
  3853. free(arg);
  3854. if (depth > 0) {
  3855. /* unwind */
  3856. oWARN(optionerrbuf);
  3857. return o_ARG_FILE_ERR;
  3858. } else {
  3859. oERR(ZE_PARMS, optionerrbuf);
  3860. }
  3861. }
  3862. }
  3863. } else if (options[match].value_type == o_NO_VALUE) {
  3864. /* this option does not accept a value */
  3865. if (valuestart) {
  3866. /* --option=value */
  3867. optionerr(optionerrbuf, op_no_allow_val_err, match, 1);
  3868. free(arg);
  3869. if (depth > 0) {
  3870. oWARN(optionerrbuf);
  3871. return o_ARG_FILE_ERR;
  3872. } else {
  3873. oERR(ZE_PARMS, optionerrbuf);
  3874. }
  3875. }
  3876. }
  3877. free(arg);
  3878. *option_num = match;
  3879. return options[match].option_ID;
  3880. }
  3881. /* get_option
  3882. *
  3883. * Main interface for user. Use this function to get options, values and
  3884. * non-option arguments from a command line provided in argv form.
  3885. *
  3886. * To use get_option() first define valid options by setting
  3887. * the global variable options[] to an array of option_struct. Also
  3888. * either change defaults below or make variables global and set elsewhere.
  3889. * Zip uses below defaults.
  3890. *
  3891. * Call get_option() to get an option (like -b or --temp-file) and any
  3892. * value for that option (like filename for -b) or a non-option argument
  3893. * (like archive name) each call. If *value* is not NULL after calling
  3894. * get_option() it is a returned value and the caller should either store
  3895. * the char pointer or free() it before calling get_option() again to avoid
  3896. * leaking memory. If a non-option non-value argument is returned get_option()
  3897. * returns o_NON_OPTION_ARG and value is set to the entire argument.
  3898. * When there are no more arguments get_option() returns 0.
  3899. *
  3900. * The parameters argnum (after set to 0 on initial call),
  3901. * optchar, first_nonopt_arg, option_num, and depth (after initial
  3902. * call) are set and maintained by get_option() and should not be
  3903. * changed. The parameters argc, negated, and value are outputs and
  3904. * can be used by the calling program. get_option() returns either the
  3905. * option_ID for the current option, a special value defined in
  3906. * zip.h, or 0 when no more arguments.
  3907. *
  3908. * The value returned by get_option() is the ID value in the options
  3909. * table. This value can be duplicated in the table if different
  3910. * options are really the same option. The index into the options[]
  3911. * table is given by option_num, though the ID should be used as
  3912. * option numbers change when the table is changed. The ID must
  3913. * not be 0 for any option as this ends the table. If get_option()
  3914. * finds an option not in the table it calls oERR to post an
  3915. * error and exit. Errors also result if the option requires a
  3916. * value that is missing, a value is present but the option does
  3917. * not take one, and an option is negated but is not
  3918. * negatable. Non-option arguments return o_NON_OPTION_ARG
  3919. * with the entire argument in value.
  3920. *
  3921. * For Zip, permuting is on and all options and their values are
  3922. * returned before any non-option arguments like archive name.
  3923. *
  3924. * The arguments "-" alone and "--" alone return as non-option arguments.
  3925. * Note that "-" should not be used as part of a short option
  3926. * entry in the table but can be used in the middle of long
  3927. * options such as in the long option "a-long-option". Now "--" alone
  3928. * stops option processing, returning any arguments following "--" as
  3929. * non-option arguments instead of options.
  3930. *
  3931. * Argument file support is removed from this version. It may be added later.
  3932. *
  3933. * After each call:
  3934. * argc is set to the current size of args[] but should not change
  3935. * with argument file support removed,
  3936. * argnum is the index of the current arg,
  3937. * value is either the value of the returned option or non-option
  3938. * argument or NULL if option with no value,
  3939. * negated is set if the option was negated by a trailing dash (-)
  3940. * option_num is set to either the index in options[] for the option or
  3941. * o_NO_OPTION_MATCH if no match.
  3942. * Negation is checked before the value is read if the option is negatable so
  3943. * that the - is not included in the value. If the option is not negatable
  3944. * but takes a value then the - will start the value. If permuting then
  3945. * argnum and first_nonopt_arg are unreliable and should not be used.
  3946. *
  3947. * Command line is read from left to right. As get_option() finds non-option
  3948. * arguments (arguments not starting with - and that are not values to options)
  3949. * it moves later options and values in front of the non-option arguments.
  3950. * This permuting is turned off by setting enable_permute to 0. Then
  3951. * get_option() will return options and non-option arguments in the order
  3952. * found. Currently permuting is only done after an argument is completely
  3953. * processed so that any value can be moved with options they go with. All
  3954. * state information is stored in the parameters argnum, optchar,
  3955. * first_nonopt_arg and option_num. You should not change these after the
  3956. * first call to get_option(). If you need to back up to a previous arg then
  3957. * set argnum to that arg (remembering that args may have been permuted) and
  3958. * set optchar = 0 and first_nonopt_arg to the first non-option argument if
  3959. * permuting. After all arguments are returned the next call to get_option()
  3960. * returns 0. The caller can then call free_args(args) if appropriate.
  3961. *
  3962. * get_option() accepts arguments in the following forms:
  3963. * short options
  3964. * of 1 and 2 characters, e.g. a, b, cc, d, and ba, after a single
  3965. * leading -, as in -abccdba. In this example if 'b' is followed by 'a'
  3966. * it matches short option 'ba' else it is interpreted as short option
  3967. * b followed by another option. The character - is not legal as a
  3968. * short option or as part of a 2 character short option.
  3969. *
  3970. * If a short option has a value it immediately follows the option or
  3971. * if that option is the end of the arg then the next arg is used as
  3972. * the value. So if short option e has a value, it can be given as
  3973. * -evalue
  3974. * or
  3975. * -e value
  3976. * and now
  3977. * -e=value
  3978. * but now that = is optional a leading = is stripped for the first.
  3979. * This change allows optional short option values to be defaulted as
  3980. * -e=
  3981. * Either optional or required values can be specified. Optional values
  3982. * now use both forms as ignoring the later got confusing. Any
  3983. * non-value short options can preceed a valued short option as in
  3984. * -abevalue
  3985. * Some value types (one_char and number) allow options after the value
  3986. * so if oc is an option that takes a character and n takes a number
  3987. * then
  3988. * -abocVccn42evalue
  3989. * returns value V for oc and value 42 for n. All values are strings
  3990. * so programs may have to convert the "42" to a number. See long
  3991. * options below for how value lists are handled.
  3992. *
  3993. * Any short option can be negated by following it with -. Any - is
  3994. * handled and skipped over before any value is read unless the option
  3995. * is not negatable but takes a value and then - starts the value.
  3996. *
  3997. * If the value for an optional value is just =, then treated as no
  3998. * value.
  3999. *
  4000. * long options
  4001. * of arbitrary length are assumed if an arg starts with -- but is not
  4002. * exactly --. Long options are given one per arg and can be abbreviated
  4003. * if the abbreviation uniquely matches one of the long options.
  4004. * Exact matches always match before partial matches. If ambiguous an
  4005. * error is generated.
  4006. *
  4007. * Values are specified either in the form
  4008. * --longoption=value
  4009. * or can be the following arg if the value is required as in
  4010. * --longoption value
  4011. * Optional values to long options must be in the first form.
  4012. *
  4013. * Value lists are specified by o_VALUE_LIST and consist of an option
  4014. * that takes a value followed by one or more value arguments.
  4015. * The two forms are
  4016. * --option=value
  4017. * or
  4018. * -ovalue
  4019. * for a single value or
  4020. * --option value1 value2 value3 ... --option2
  4021. * or
  4022. * -o value1 value2 value3 ...
  4023. * for a list of values. The list ends at the next option, the
  4024. * end of the command line, or at a single "@" argument.
  4025. * Each value is treated as if it was preceeded by the option, so
  4026. * --option1 val1 val2
  4027. * with option1 value_type set to o_VALUE_LIST is the same as
  4028. * --option1=val1 --option1=val2
  4029. *
  4030. * Long options can be negated by following the option with - as in
  4031. * --longoption-
  4032. * Long options with values can also be negated if this makes sense for
  4033. * the caller as:
  4034. * --longoption-=value
  4035. * If = is not followed by anything it is treated as no value.
  4036. *
  4037. * @path
  4038. * When an argument in the form @path is encountered, the file at path
  4039. * is opened and white space separated arguments read from the file
  4040. * and inserted into the command line at that point as if the contents
  4041. * of the file were directly typed at that location. The file can
  4042. * have options, files to zip, or anything appropriate at that location
  4043. * in the command line. Since Zip has permuting enabled, options and
  4044. * files will propagate to the appropriate locations in the command
  4045. * line.
  4046. *
  4047. * Argument files support has been removed from this version. It may
  4048. * be added back later.
  4049. *
  4050. * non-option argument
  4051. * is any argument not given above. If enable_permute is 1 then
  4052. * these are returned after all options, otherwise all options and
  4053. * args are returned in order. Returns option ID o_NON_OPTION_ARG
  4054. * and sets value to the argument.
  4055. *
  4056. *
  4057. * Arguments to get_option:
  4058. * char ***pargs - pointer to arg array in the argv form
  4059. * int *argc - returns the current argc for args incl. args[0]
  4060. * int *argnum - the index of the current argument (caller
  4061. * should set = 0 on first call and not change
  4062. * after that)
  4063. * int *optchar - index of next short opt in arg or special
  4064. * int *first_nonopt_arg - used by get_option to permute args
  4065. * int *negated - option was negated (had trailing -)
  4066. * char *value - value of option if any (free when done with it) or NULL
  4067. * int *option_num - the index in options of the last option returned
  4068. * (can be o_NO_OPTION_MATCH)
  4069. * int recursion_depth - current depth of recursion
  4070. * (always set to 0 by caller)
  4071. * (always 0 with argument files support removed)
  4072. *
  4073. * Caller should only read the returned option ID and the value, negated,
  4074. * and option_num (if required) parameters after each call.
  4075. *
  4076. * Ed Gordon
  4077. * 24 August 2003 (last updated 2 April 2008 EG)
  4078. *
  4079. */
  4080. unsigned long get_option(pargs, argc, argnum, optchar, value,
  4081. negated, first_nonopt_arg, option_num, recursion_depth)
  4082. char ***pargs;
  4083. int *argc;
  4084. int *argnum;
  4085. int *optchar;
  4086. char **value;
  4087. int *negated;
  4088. int *first_nonopt_arg;
  4089. int *option_num;
  4090. int recursion_depth;
  4091. {
  4092. char **args;
  4093. unsigned long option_ID;
  4094. int argcnt;
  4095. int first_nonoption_arg;
  4096. char *arg = NULL;
  4097. int h;
  4098. int optc;
  4099. int argn;
  4100. int j;
  4101. int v;
  4102. int read_rest_args_verbatim = 0; /* 7/25/04 - ignore options and arg files for rest args */
  4103. /* value is outdated. The caller should free value before
  4104. calling get_option again. */
  4105. *value = NULL;
  4106. /* if args is NULL then done */
  4107. if (pargs == NULL) {
  4108. *argc = 0;
  4109. return 0;
  4110. }
  4111. args = *pargs;
  4112. if (args == NULL) {
  4113. *argc = 0;
  4114. return 0;
  4115. }
  4116. /* count args */
  4117. for (argcnt = 0; args[argcnt]; argcnt++) ;
  4118. /* if no provided args then nothing to do */
  4119. if (argcnt < 1 || (recursion_depth == 0 && argcnt < 2)) {
  4120. *argc = argcnt;
  4121. /* return 0 to note that no args are left */
  4122. return 0;
  4123. }
  4124. *negated = 0;
  4125. first_nonoption_arg = *first_nonopt_arg;
  4126. argn = *argnum;
  4127. optc = *optchar;
  4128. if (optc == READ_REST_ARGS_VERBATIM) {
  4129. read_rest_args_verbatim = 1;
  4130. }
  4131. if (argn == -1 || (recursion_depth == 0 && argn == 0)) {
  4132. /* first call */
  4133. /* if depth = 0 then args[0] is argv[0] so skip */
  4134. *option_num = o_NO_OPTION_MATCH;
  4135. optc = THIS_ARG_DONE;
  4136. first_nonoption_arg = -1;
  4137. }
  4138. /* if option_num is set then restore last option_ID in case continuing value list */
  4139. option_ID = 0;
  4140. if (*option_num != o_NO_OPTION_MATCH) {
  4141. option_ID = options[*option_num].option_ID;
  4142. }
  4143. /* get next option if any */
  4144. for (;;) {
  4145. if (read_rest_args_verbatim) {
  4146. /* rest of args after "--" are non-option args if doubledash_ends_options set */
  4147. argn++;
  4148. if (argn > argcnt || args[argn] == NULL) {
  4149. /* done */
  4150. option_ID = 0;
  4151. break;
  4152. }
  4153. arg = args[argn];
  4154. if ((*value = (char *)malloc(strlen(arg) + 1)) == NULL) {
  4155. oERR(ZE_MEM, "go");
  4156. }
  4157. strcpy(*value, arg);
  4158. *option_num = o_NO_OPTION_MATCH;
  4159. option_ID = o_NON_OPTION_ARG;
  4160. break;
  4161. /* permute non-option args after option args so options are returned first */
  4162. } else if (enable_permute) {
  4163. if (optc == SKIP_VALUE_ARG || optc == THIS_ARG_DONE ||
  4164. optc == START_VALUE_LIST || optc == IN_VALUE_LIST ||
  4165. optc == STOP_VALUE_LIST) {
  4166. /* moved to new arg */
  4167. if (first_nonoption_arg > -1 && args[first_nonoption_arg]) {
  4168. /* do the permuting - move non-options after this option */
  4169. /* if option and value separate args or starting list skip option */
  4170. if (optc == SKIP_VALUE_ARG || optc == START_VALUE_LIST) {
  4171. v = 1;
  4172. } else {
  4173. v = 0;
  4174. }
  4175. for (h = first_nonoption_arg; h < argn; h++) {
  4176. arg = args[first_nonoption_arg];
  4177. for (j = first_nonoption_arg; j < argn + v; j++) {
  4178. args[j] = args[j + 1];
  4179. }
  4180. args[j] = arg;
  4181. }
  4182. first_nonoption_arg += 1 + v;
  4183. }
  4184. }
  4185. } else if (optc == NON_OPTION_ARG) {
  4186. /* if not permuting then already returned arg */
  4187. optc = THIS_ARG_DONE;
  4188. }
  4189. /* value lists */
  4190. if (optc == STOP_VALUE_LIST) {
  4191. optc = THIS_ARG_DONE;
  4192. }
  4193. if (optc == START_VALUE_LIST || optc == IN_VALUE_LIST) {
  4194. if (optc == START_VALUE_LIST) {
  4195. /* already returned first value */
  4196. argn++;
  4197. optc = IN_VALUE_LIST;
  4198. }
  4199. argn++;
  4200. arg = args[argn];
  4201. /* if end of args and still in list and there are non-option args then
  4202. terminate list */
  4203. if (arg == NULL && (optc == START_VALUE_LIST || optc == IN_VALUE_LIST)
  4204. && first_nonoption_arg > -1) {
  4205. /* terminate value list with @ */
  4206. /* this is only needed for argument files */
  4207. /* but is also good for show command line so command lines with lists
  4208. can always be read back in */
  4209. argcnt = insert_arg(&args, "@", first_nonoption_arg, 1);
  4210. argn++;
  4211. if (first_nonoption_arg > -1) {
  4212. first_nonoption_arg++;
  4213. }
  4214. }
  4215. arg = args[argn];
  4216. if (arg && arg[0] == '@' && arg[1] == '\0') {
  4217. /* inserted arguments terminator */
  4218. optc = STOP_VALUE_LIST;
  4219. continue;
  4220. } else if (arg && arg[0] != '-') { /* not option */
  4221. /* - and -- are not allowed in value lists unless escaped */
  4222. /* another value in value list */
  4223. if ((*value = (char *)malloc(strlen(args[argn]) + 1)) == NULL) {
  4224. oERR(ZE_MEM, "go");
  4225. }
  4226. strcpy(*value, args[argn]);
  4227. break;
  4228. } else {
  4229. argn--;
  4230. optc = THIS_ARG_DONE;
  4231. }
  4232. }
  4233. /* move to next arg */
  4234. if (optc == SKIP_VALUE_ARG) {
  4235. argn += 2;
  4236. optc = 0;
  4237. } else if (optc == THIS_ARG_DONE) {
  4238. argn++;
  4239. optc = 0;
  4240. }
  4241. if (argn > argcnt) {
  4242. break;
  4243. }
  4244. if (args[argn] == NULL) {
  4245. /* done unless permuting and non-option args */
  4246. if (first_nonoption_arg > -1 && args[first_nonoption_arg]) {
  4247. /* return non-option arguments at end */
  4248. if (optc == NON_OPTION_ARG) {
  4249. first_nonoption_arg++;
  4250. }
  4251. /* after first pass args are permuted but skipped over non-option args */
  4252. /* swap so argn points to first non-option arg */
  4253. j = argn;
  4254. argn = first_nonoption_arg;
  4255. first_nonoption_arg = j;
  4256. }
  4257. if (argn > argcnt || args[argn] == NULL) {
  4258. /* done */
  4259. option_ID = 0;
  4260. break;
  4261. }
  4262. }
  4263. /* after swap first_nonoption_arg points to end which is NULL */
  4264. if (first_nonoption_arg > -1 && (args[first_nonoption_arg] == NULL)) {
  4265. /* only non-option args left */
  4266. if (optc == NON_OPTION_ARG) {
  4267. argn++;
  4268. }
  4269. if (argn > argcnt || args[argn] == NULL) {
  4270. /* done */
  4271. option_ID = 0;
  4272. break;
  4273. }
  4274. if ((*value = (char *)malloc(strlen(args[argn]) + 1)) == NULL) {
  4275. oERR(ZE_MEM, "go");
  4276. }
  4277. strcpy(*value, args[argn]);
  4278. optc = NON_OPTION_ARG;
  4279. option_ID = o_NON_OPTION_ARG;
  4280. break;
  4281. }
  4282. arg = args[argn];
  4283. /* is it an option */
  4284. if (arg[0] == '-') {
  4285. /* option */
  4286. if (arg[1] == '\0') {
  4287. /* arg = - */
  4288. /* treat like non-option arg */
  4289. *option_num = o_NO_OPTION_MATCH;
  4290. if (enable_permute) {
  4291. /* permute args to move all non-option args to end */
  4292. if (first_nonoption_arg < 0) {
  4293. first_nonoption_arg = argn;
  4294. }
  4295. argn++;
  4296. } else {
  4297. /* not permute args so return non-option args when found */
  4298. if ((*value = (char *)malloc(strlen(arg) + 1)) == NULL) {
  4299. oERR(ZE_MEM, "go");
  4300. }
  4301. strcpy(*value, arg);
  4302. optc = NON_OPTION_ARG;
  4303. option_ID = o_NON_OPTION_ARG;
  4304. break;
  4305. }
  4306. } else if (arg[1] == '-') {
  4307. /* long option */
  4308. if (arg[2] == '\0') {
  4309. /* arg = -- */
  4310. if (doubledash_ends_options) {
  4311. /* Now -- stops permuting and forces the rest of
  4312. the command line to be read verbatim - 7/25/04 EG */
  4313. /* never permute args after -- and return as non-option args */
  4314. if (first_nonoption_arg < 1) {
  4315. /* -- is first non-option argument - 8/7/04 EG */
  4316. argn--;
  4317. } else {
  4318. /* go back to start of non-option args - 8/7/04 EG */
  4319. argn = first_nonoption_arg - 1;
  4320. }
  4321. /* disable permuting and treat remaining arguments as not
  4322. options */
  4323. read_rest_args_verbatim = 1;
  4324. optc = READ_REST_ARGS_VERBATIM;
  4325. } else {
  4326. /* treat like non-option arg */
  4327. *option_num = o_NO_OPTION_MATCH;
  4328. if (enable_permute) {
  4329. /* permute args to move all non-option args to end */
  4330. if (first_nonoption_arg < 0) {
  4331. first_nonoption_arg = argn;
  4332. }
  4333. argn++;
  4334. } else {
  4335. /* not permute args so return non-option args when found */
  4336. if ((*value = (char *)malloc(strlen(arg) + 1)) == NULL) {
  4337. oERR(ZE_MEM, "go");
  4338. }
  4339. strcpy(*value, arg);
  4340. optc = NON_OPTION_ARG;
  4341. option_ID = o_NON_OPTION_ARG;
  4342. break;
  4343. }
  4344. }
  4345. } else {
  4346. option_ID = get_longopt(args, argn, &optc, negated, value, option_num, recursion_depth);
  4347. if (option_ID == o_ARG_FILE_ERR) {
  4348. /* unwind as only get this if recursion_depth > 0 */
  4349. return option_ID;
  4350. }
  4351. break;
  4352. }
  4353. } else {
  4354. /* short option */
  4355. option_ID = get_shortopt(args, argn, &optc, negated, value, option_num, recursion_depth);
  4356. if (option_ID == o_ARG_FILE_ERR) {
  4357. /* unwind as only get this if recursion_depth > 0 */
  4358. return option_ID;
  4359. }
  4360. if (optc == 0) {
  4361. /* if optc = 0 then ran out of short opts this arg */
  4362. optc = THIS_ARG_DONE;
  4363. } else {
  4364. break;
  4365. }
  4366. }
  4367. #if 0
  4368. /* argument file code left out
  4369. so for now let filenames start with @
  4370. */
  4371. } else if (allow_arg_files && arg[0] == '@') {
  4372. /* arg file */
  4373. oERR(ZE_PARMS, no_arg_files_err);
  4374. #endif
  4375. } else {
  4376. /* non-option */
  4377. if (enable_permute) {
  4378. /* permute args to move all non-option args to end */
  4379. if (first_nonoption_arg < 0) {
  4380. first_nonoption_arg = argn;
  4381. }
  4382. argn++;
  4383. } else {
  4384. /* no permute args so return non-option args when found */
  4385. if ((*value = (char *)malloc(strlen(arg) + 1)) == NULL) {
  4386. oERR(ZE_MEM, "go");
  4387. }
  4388. strcpy(*value, arg);
  4389. *option_num = o_NO_OPTION_MATCH;
  4390. optc = NON_OPTION_ARG;
  4391. option_ID = o_NON_OPTION_ARG;
  4392. break;
  4393. }
  4394. }
  4395. }
  4396. *pargs = args;
  4397. *argc = argcnt;
  4398. *first_nonopt_arg = first_nonoption_arg;
  4399. *argnum = argn;
  4400. *optchar = optc;
  4401. return option_ID;
  4402. }