extrafld.c 32 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920
  1. /*
  2. Copyright (c) 1990-2002 Info-ZIP. All rights reserved.
  3. See the accompanying file LICENSE, version 2000-Apr-09 or later
  4. (the contents of which are also included in zip.h) for terms of use.
  5. If, for some reason, all these files are missing, the Info-ZIP license
  6. also may be found at: ftp://ftp.info-zip.org/pub/infozip/license.html
  7. */
  8. /*---------------------------------------------------------------------------
  9. extrafld.c
  10. contains functions to build extra-fields.
  11. ---------------------------------------------------------------------------*/
  12. /*****************************************************************************/
  13. /* Includes */
  14. /*****************************************************************************/
  15. #include <sound.h>
  16. #include "zip.h"
  17. #include "unixlike.h"
  18. #include "helpers.h"
  19. #include "pathname.h"
  20. /*****************************************************************************/
  21. /* Macros, typedefs */
  22. /*****************************************************************************/
  23. /* ---------------------------------------------------------------------- */
  24. /* Add a 'MAC3' extra field to the zlist data pointed to by z. */
  25. /* This is the (new) Info-zip extra block for Macintosh */
  26. #define EB_MAC3_HLEN 14 /* fixed length part of MAC3's header */
  27. #define EB_L_MAC3_FINFO_LEN 52 /* fixed part of MAC3 compressible data */
  28. #define EB_MAX_OF_VARDATA 1300 /* max possible datasize */
  29. #define EB_L_MAC3_SIZE (EB_HEADSIZE + EB_MAC3_HLEN)
  30. #define EB_C_MAC3_SIZE (EB_HEADSIZE + EB_MAC3_HLEN)
  31. /* maximum memcompress overhead is the sum of the compression header length */
  32. /* (6 = ush compression type, ulg CRC) and the worstcase deflate overhead */
  33. /* when uncompressible data are kept in 2 "stored" blocks (5 per block = */
  34. /* byte blocktype + 2 * ush blocklength) */
  35. #define MEMCOMPRESS_OVERHEAD (EB_MEMCMPR_HSIZ + EB_DEFLAT_EXTRA)
  36. #define EB_M3_FL_COMPRESS 0x00
  37. #define EB_M3_FL_DATFRK 0x01 /* data is data-fork */
  38. #define EB_M3_FL_NOCHANGE 0x02 /* filename will be not changed */
  39. #define EB_M3_FL_UNCMPR 0x04 /* data is 'natural' (not compressed) */
  40. #define EB_M3_FL_TIME64 0x08 /* time is coded in 64 bit */
  41. #define EB_M3_FL_NOUTC 0x10 /* only 'local' time-stamps are stored */
  42. #define EB_L_UT_SIZE (EB_HEADSIZE + EB_UT_LEN(2))
  43. #define EB_C_UT_SIZE (EB_HEADSIZE + EB_UT_LEN(1))
  44. /* disable compressing of extra field
  45. #define MAC_EXTRAFLD_UNCMPR */
  46. /* ---------------------------------------------------------------------- */
  47. /* Add a 'JLEE' extra field to the zlist data pointed to by z. */
  48. /* This is the (old) Info-zip resource-fork extra block for Macintosh
  49. (last Revision 1996-09-22) Layout made by Johnny Lee, Code made by me :-) */
  50. #define EB_L_JLEE_LEN 40 /* fixed length of JLEE's header */
  51. #define EB_C_JLEE_LEN 40 /* fixed length of JLEE's header */
  52. #define EB_L_JLEE_SIZE (EB_HEADSIZE + EB_L_JLEE_LEN)
  53. #define EB_C_JLEE_SIZE (EB_HEADSIZE + EB_C_JLEE_LEN)
  54. /*****************************************************************************/
  55. /* Global Vars */
  56. /*****************************************************************************/
  57. extern MacZipGlobals MacZip;
  58. extern unsigned long count_of_Zippedfiles;
  59. /*****************************************************************************/
  60. /* Prototypes */
  61. /*****************************************************************************/
  62. static int add_UT_ef(struct zlist far *z, iztimes *z_utim);
  63. static int add_JLEE_ef(struct zlist far *z); /* old mac extra field */
  64. static int add_MAC3_ef(struct zlist far *z); /* new mac extra field */
  65. static void make_extrafield_JLEE(char *l_ef);
  66. static unsigned make_extrafield_MAC3(char *ef);
  67. static char *make_EF_Head_MAC3(char *ef, unsigned compsize, ulg attrsize,
  68. unsigned flag);
  69. static void print_extra_info(void);
  70. void UserStop(void);
  71. /*****************************************************************************/
  72. /* Functions */
  73. /*****************************************************************************/
  74. /*
  75. * Set the extra-field's for each compressed file
  76. */
  77. int set_extra_field(struct zlist far *z, iztimes *z_utim)
  78. /* store full data in local header but just modification time stamp info
  79. in central header */
  80. {
  81. int retval;
  82. Assert_it(z, "set_extra_field","")
  83. Assert_it(z_utim, "set_extra_field","")
  84. z_utim = z_utim;
  85. /* Check to make sure z is valid. */
  86. if( z == NULL ) {
  87. return ZE_LOGIC;
  88. }
  89. /* Resource forks are always binary */
  90. if (MacZip.CurrentFork == ResourceFork) z->att = BINARY;
  91. if (noisy)
  92. {
  93. count_of_Zippedfiles++;
  94. InformProgress(MacZip.RawCountOfItems, count_of_Zippedfiles );
  95. }
  96. /*
  97. PrintFileInfo();
  98. */
  99. switch (MacZip.MacZipMode)
  100. {
  101. case JohnnyLee_EF:
  102. {
  103. retval = add_JLEE_ef( z );
  104. if (retval != ZE_OK) return retval;
  105. break;
  106. }
  107. case NewZipMode_EF:
  108. { /* */
  109. #ifdef USE_EF_UT_TIME
  110. retval = add_UT_ef(z, z_utim);
  111. if (retval != ZE_OK) return retval;
  112. #endif
  113. retval = add_MAC3_ef( z );
  114. if (retval != ZE_OK) return retval;
  115. break;
  116. }
  117. default:
  118. {
  119. printerr("Unknown Extrafieldmode", -1, -1, __LINE__, __FILE__, "");
  120. return ZE_LOGIC; /* function should never reach this point */
  121. }
  122. }
  123. /* MacStat information is now outdated and
  124. must be refreshed for the next file */
  125. MacZip.isMacStatValid = false;
  126. return ZE_OK;
  127. }
  128. #ifdef USE_EF_UT_TIME
  129. /*
  130. * Build and add the Unix time extra-field. This extra field
  131. * will be included be default. Johnny Lee's implementation does
  132. * not use this kind of extra-field.
  133. * All datas are in Intel (=little-endian) format
  134. Extra field info:
  135. - 'UT' - UNIX time extra field
  136. This is done the same way ../unix/unix.c stores the 'UT'/'Ux' fields
  137. (full data in local header, only modification time in central header),
  138. with the 'M3' field added to the end and the size of the 'M3' field
  139. in the central header.
  140. */
  141. static int add_UT_ef(struct zlist far *z, iztimes *z_utim)
  142. {
  143. char *l_ef = NULL;
  144. char *c_ef = NULL;
  145. Assert_it(z, "add_UT_ef","")
  146. #ifdef IZ_CHECK_TZ
  147. if (!zp_tz_is_valid)
  148. return ZE_OK; /* skip silently if no valid TZ info */
  149. #endif
  150. /* We can't work if there's no entry to work on. */
  151. if( z == NULL ) {
  152. return ZE_LOGIC;
  153. }
  154. /* Check to make sure we've got enough room in the extra fields. */
  155. if( z->ext + EB_L_UT_SIZE > EF_SIZE_MAX ||
  156. z->cext + EB_C_UT_SIZE > EF_SIZE_MAX ) {
  157. return ZE_MEM;
  158. }
  159. /* Allocate memory for the local and central extra fields. */
  160. if( z->extra && z->ext != 0 ) {
  161. l_ef = (char *)realloc( z->extra, z->ext + EB_L_UT_SIZE );
  162. } else {
  163. l_ef = (char *)malloc( EB_L_UT_SIZE );
  164. z->ext = 0;
  165. }
  166. if( l_ef == NULL ) {
  167. return ZE_MEM;
  168. }
  169. z->extra = l_ef;
  170. l_ef += z->ext;
  171. if( z->cextra && z->cext != 0 ) {
  172. c_ef = (char *)realloc( z->cextra, z->cext + EB_C_UT_SIZE );
  173. } else {
  174. c_ef = (char *)malloc( EB_C_UT_SIZE );
  175. z->cext = 0;
  176. }
  177. if( c_ef == NULL ) {
  178. return ZE_MEM;
  179. }
  180. z->cextra = c_ef;
  181. c_ef += z->cext;
  182. /* Now add the local version of the field. */
  183. *l_ef++ = 'U';
  184. *l_ef++ = 'T';
  185. *l_ef++ = (char)(EB_UT_LEN(2)); /* length of data in local EF */
  186. *l_ef++ = (char)0;
  187. *l_ef++ = (char)(EB_UT_FL_MTIME | EB_UT_FL_CTIME);
  188. *l_ef++ = (char)(z_utim->mtime);
  189. *l_ef++ = (char)(z_utim->mtime >> 8);
  190. *l_ef++ = (char)(z_utim->mtime >> 16);
  191. *l_ef++ = (char)(z_utim->mtime >> 24);
  192. *l_ef++ = (char)(z_utim->ctime);
  193. *l_ef++ = (char)(z_utim->ctime >> 8);
  194. *l_ef++ = (char)(z_utim->ctime >> 16);
  195. *l_ef++ = (char)(z_utim->ctime >> 24);
  196. z->ext += EB_L_UT_SIZE;
  197. /* Now add the central version. */
  198. memcpy(c_ef, l_ef-EB_L_UT_SIZE, EB_C_UT_SIZE);
  199. c_ef[EB_LEN] = (char)(EB_UT_LEN(1)); /* length of data in central EF */
  200. z->cext += EB_C_UT_SIZE;
  201. return ZE_OK;
  202. }
  203. #endif /* USE_EF_UT_TIME */
  204. /*
  205. * Build and add the old 'Johnny Lee' Mac extra field
  206. * All native datas are in Motorola (=big-endian) format
  207. */
  208. static int add_JLEE_ef( struct zlist far *z )
  209. {
  210. char *l_ef = NULL;
  211. char *c_ef = NULL;
  212. Assert_it(z, "add_JLEE_ef","")
  213. /* Check to make sure we've got enough room in the extra fields. */
  214. if ( z->ext + EB_L_JLEE_SIZE > EF_SIZE_MAX ||
  215. z->cext + EB_C_JLEE_SIZE > EF_SIZE_MAX ) {
  216. return ZE_MEM;
  217. }
  218. /* Allocate memory for the local extra fields. */
  219. if ( z->extra && z->ext != 0 ) {
  220. l_ef = (char *)realloc( z->extra, z->ext + EB_L_JLEE_SIZE );
  221. } else {
  222. l_ef = (char *)malloc( EB_L_JLEE_SIZE );
  223. z->ext = 0;
  224. }
  225. if ( l_ef == NULL ) {
  226. return ZE_MEM;
  227. }
  228. z->extra = l_ef;
  229. l_ef += z->ext;
  230. /* Allocate memory for the central extra fields. */
  231. if ( z->cextra && z->cext != 0 ) {
  232. c_ef = (char *)realloc( z->cextra, z->cext + EB_C_JLEE_SIZE );
  233. } else {
  234. c_ef = (char *)malloc( EB_C_JLEE_SIZE );
  235. z->cext = 0;
  236. }
  237. if ( c_ef == NULL ) {
  238. return ZE_MEM;
  239. }
  240. z->cextra = c_ef;
  241. c_ef += z->cext;
  242. if ( verbose ) {
  243. print_extra_info();
  244. }
  245. /**
  246. **
  247. ** Now add the local version of the field.
  248. **/
  249. make_extrafield_JLEE(l_ef);
  250. z->ext += EB_L_JLEE_SIZE;
  251. /**
  252. **
  253. ** Now add the central version of the field.
  254. ** It's identical to the local header. I wonder why ??
  255. * the first two fields are in Intel little-endian format */
  256. make_extrafield_JLEE(c_ef);
  257. z->cext += EB_C_JLEE_SIZE;
  258. return ZE_OK;
  259. }
  260. /*
  261. * This is an implementation of Johnny Lee's extra field.
  262. * I never saw Johnny Lee's code. My code is based on the extra-field
  263. * definition mac (see latest appnote 1997-03-11)
  264. * and on some experiments with Johnny Lee's Zip-app version 1.0, 1992
  265. *
  266. * Unfortunately I cannot agree with his extra-field layout.
  267. * - it wasted space
  268. * - and holds not all mac-specific information
  269. *
  270. * I coded this extra-field only for testing purposes.
  271. * I don't want support this extra-field. Please use my implementation.
  272. *
  273. * This is old implementation of Johnny Lee's extra field.
  274. * All native datas are in Motorola (=big-endian) format
  275. */
  276. static void make_extrafield_JLEE(char *ef)
  277. {
  278. Assert_it(ef, "make_extrafield_JLEE","")
  279. if (MacZip.isMacStatValid == false)
  280. {
  281. fprintf(stderr,"Internal Logic Error: [%d/%s] MacStat is out of sync !",
  282. __LINE__,__FILE__);
  283. exit(-1);
  284. }
  285. /* the first two fields are in Intel little-endian format */
  286. *ef++ = 0xC8; /* tag for this extra block */
  287. *ef++ = 0x07;
  288. *ef++ = (char)(EB_L_JLEE_LEN); /* total data size this block */
  289. *ef++ = (char)((EB_L_JLEE_LEN) >> 8);
  290. /* the following fields are in motorola big-endian format */
  291. *ef++ = 'J'; /* extra field signature: 4 Bytes */
  292. *ef++ = 'L'; /* the old style extra field */
  293. *ef++ = 'E';
  294. *ef++ = 'E';
  295. /* Start Macintosh Finder FInfo structure 16 Bytes overall */
  296. /* Type: 4 Bytes */
  297. *ef++ = (char)(MacZip.fpb.hFileInfo.ioFlFndrInfo.fdType >> 24);
  298. *ef++ = (char)(MacZip.fpb.hFileInfo.ioFlFndrInfo.fdType >> 16);
  299. *ef++ = (char)(MacZip.fpb.hFileInfo.ioFlFndrInfo.fdType >> 8);
  300. *ef++ = (char)(MacZip.fpb.hFileInfo.ioFlFndrInfo.fdType);
  301. /* Creator: 4 Bytes */
  302. *ef++ = (char)(MacZip.fpb.hFileInfo.ioFlFndrInfo.fdCreator >> 24);
  303. *ef++ = (char)(MacZip.fpb.hFileInfo.ioFlFndrInfo.fdCreator >> 16);
  304. *ef++ = (char)(MacZip.fpb.hFileInfo.ioFlFndrInfo.fdCreator >> 8);
  305. *ef++ = (char)(MacZip.fpb.hFileInfo.ioFlFndrInfo.fdCreator);
  306. /* file Finder Flags: 2 Bytes */
  307. *ef++ = (char)(MacZip.fpb.hFileInfo.ioFlFndrInfo.fdFlags >> 8);
  308. *ef++ = (char)(MacZip.fpb.hFileInfo.ioFlFndrInfo.fdFlags);
  309. /* Finders Icon position of a file*/
  310. /* V/Y-Position: 2 Bytes */
  311. *ef++ = (char)(MacZip.fpb.hFileInfo.ioFlFndrInfo.fdLocation.v >> 8);
  312. *ef++ = (char)(MacZip.fpb.hFileInfo.ioFlFndrInfo.fdLocation.v);
  313. /* H/X-Position: 2 Bytes */
  314. *ef++ = (char)(MacZip.fpb.hFileInfo.ioFlFndrInfo.fdLocation.h >> 8);
  315. *ef++ = (char)(MacZip.fpb.hFileInfo.ioFlFndrInfo.fdLocation.h);
  316. /* fdFldr Folder containing file 2 Bytes */
  317. *ef++ = (char)(MacZip.fpb.hFileInfo.ioFlFndrInfo.fdFldr >> 8);
  318. *ef++ = (char)(MacZip.fpb.hFileInfo.ioFlFndrInfo.fdFldr);
  319. /* End Macintosh Finder FInfo structure */
  320. /* Creation-time 4 Bytes */
  321. *ef++ = (char)(MacZip.fpb.hFileInfo.ioFlCrDat >> 24);
  322. *ef++ = (char)(MacZip.fpb.hFileInfo.ioFlCrDat >> 16);
  323. *ef++ = (char)(MacZip.fpb.hFileInfo.ioFlCrDat >> 8);
  324. *ef++ = (char)(MacZip.fpb.hFileInfo.ioFlCrDat);
  325. /* Modification-time 4 Bytes */
  326. *ef++ = (char)(MacZip.fpb.hFileInfo.ioFlMdDat >> 24);
  327. *ef++ = (char)(MacZip.fpb.hFileInfo.ioFlMdDat >> 16);
  328. *ef++ = (char)(MacZip.fpb.hFileInfo.ioFlMdDat >> 8);
  329. *ef++ = (char)(MacZip.fpb.hFileInfo.ioFlMdDat);
  330. /* info Bits 4 Bytes */
  331. *ef++ = 0x00;
  332. *ef++ = 0x00;
  333. *ef++ = 0x00;
  334. if (MacZip.DataForkOnly)
  335. { /* don't convert filename for unzipping */
  336. /* 0x01 = data-fork; 0x00 = resource-fork */
  337. *ef++ = (char) (MacZip.CurrentFork == DataFork) | 2;
  338. }
  339. else
  340. {
  341. *ef++ = (char) (MacZip.CurrentFork == DataFork);
  342. }
  343. /* file's location folder ID 4 Bytes */
  344. *ef++ = (char)(MacZip.fpb.hFileInfo.ioFlParID >> 24);
  345. *ef++ = (char)(MacZip.fpb.hFileInfo.ioFlParID >> 16);
  346. *ef++ = (char)(MacZip.fpb.hFileInfo.ioFlParID >> 8);
  347. *ef++ = (char)(MacZip.fpb.hFileInfo.ioFlParID);
  348. /* ============ */
  349. /* 40 Bytes */
  350. }
  351. /*
  352. * Build and add the new mac extra field
  353. * All native data are stored in Intel (=little-endian) format
  354. */
  355. static int add_MAC3_ef( struct zlist far *z )
  356. {
  357. char *l_ef = NULL;
  358. char *c_ef = NULL;
  359. char *attrbuff = NULL;
  360. off_t attrsize = (EB_L_MAC3_FINFO_LEN + EB_MAX_OF_VARDATA);
  361. char *compbuff = NULL;
  362. unsigned compsize = 0;
  363. unsigned m3_compr;
  364. Boolean compress_data = true;
  365. Assert_it(z, "add_MAC3_ef","")
  366. UserStop(); /* do event handling and let the user stop */
  367. if( verbose ) {
  368. print_extra_info();
  369. }
  370. /* allocate temporary buffer to collect the Mac extra field info */
  371. attrbuff = (char *)malloc( (size_t)attrsize );
  372. if( attrbuff == NULL ) {
  373. return ZE_MEM;
  374. }
  375. /* fill the attribute buffer, to get its (uncompressed) size */
  376. attrsize = make_extrafield_MAC3(attrbuff);
  377. if (compress_data &&
  378. ((compbuff = (char *)malloc((size_t)attrsize + MEMCOMPRESS_OVERHEAD))
  379. != NULL))
  380. {
  381. /* Try compressing the data */
  382. compsize = memcompress( compbuff,
  383. (size_t)attrsize + MEMCOMPRESS_OVERHEAD,
  384. attrbuff,
  385. (size_t)attrsize );
  386. #ifdef MAC_EXTRAFLD_UNCMPR
  387. compsize = attrsize;
  388. #endif
  389. }
  390. else
  391. {
  392. compsize = attrsize;
  393. }
  394. if ((compsize) < attrsize) {
  395. /* compression gained some space ... */
  396. free(attrbuff); /* no longer needed ... */
  397. m3_compr = EB_M3_FL_COMPRESS;
  398. } else {
  399. /* compression does not help, store data in uncompressed mode */
  400. if (compbuff != NULL) free(compbuff);
  401. compbuff = attrbuff;
  402. compsize = attrsize;
  403. m3_compr = EB_M3_FL_UNCMPR;
  404. }
  405. /* Check to make sure we've got enough room in the extra fields. */
  406. if( z->ext + (EB_L_MAC3_SIZE + compsize) > EF_SIZE_MAX ||
  407. z->cext + EB_C_MAC3_SIZE > EF_SIZE_MAX ) {
  408. if (compbuff != NULL) free(compbuff);
  409. return ZE_MEM;
  410. }
  411. /* Allocate memory for the local extra fields. */
  412. if( z->extra && z->ext != 0 ) {
  413. l_ef = (char *)realloc( z->extra, z->ext +
  414. EB_L_MAC3_SIZE + compsize);
  415. } else {
  416. l_ef = (char *)malloc( EB_L_MAC3_SIZE + compsize);
  417. z->ext = 0;
  418. }
  419. if( l_ef == NULL ) {
  420. return ZE_MEM;
  421. }
  422. z->extra = l_ef;
  423. l_ef += z->ext;
  424. /* Allocate memory for the central extra fields. */
  425. if( z->cextra && z->cext != 0 ) {
  426. c_ef = (char *)realloc( z->cextra, z->cext + EB_C_MAC3_SIZE);
  427. } else {
  428. c_ef = (char *)malloc( EB_C_MAC3_SIZE );
  429. z->cext = 0;
  430. }
  431. if( c_ef == NULL ) {
  432. return ZE_MEM;
  433. }
  434. z->cextra = c_ef;
  435. c_ef += z->cext;
  436. /**
  437. ** Now add the local version of the field.
  438. **/
  439. l_ef = make_EF_Head_MAC3(l_ef, compsize, (ulg)attrsize, m3_compr);
  440. memcpy(l_ef, compbuff, (size_t)compsize);
  441. l_ef += compsize;
  442. z->ext += EB_L_MAC3_SIZE + compsize;
  443. free(compbuff);
  444. /* And the central version. */
  445. c_ef = make_EF_Head_MAC3(c_ef, 0, (ulg)attrsize, m3_compr);
  446. z->cext += EB_C_MAC3_SIZE;
  447. return ZE_OK;
  448. }
  449. /*
  450. * Build the new mac local extra field header.
  451. * It's identical with the central extra field.
  452. * All native data are in Intel (=little-endian) format
  453. */
  454. static char *make_EF_Head_MAC3(char *ef, unsigned compsize, ulg attrsize,
  455. unsigned flag)
  456. {
  457. unsigned info_flag = flag;
  458. Assert_it(ef, "make_EF_Head_MAC3","")
  459. /* the first four fields are in Intel little-endian format */
  460. *ef++ = 'M'; /* tag for this extra block 2 Bytes */
  461. *ef++ = '3';
  462. /* total data size this block 2 Bytes */
  463. *ef++ = (char) (EB_MAC3_HLEN + compsize);
  464. *ef++ = (char)((EB_MAC3_HLEN + compsize) >> 8);
  465. *ef++ = (char)(attrsize);
  466. *ef++ = (char)(attrsize >> 8);
  467. *ef++ = (char)(attrsize >> 16);
  468. *ef++ = (char)(attrsize >> 24);
  469. /* info Bits (flags) 2 Bytes */
  470. if (MacZip.DataForkOnly) info_flag |= (EB_M3_FL_DATFRK |
  471. EB_M3_FL_NOCHANGE);
  472. if (MacZip.CurrentFork == DataFork) info_flag |= EB_M3_FL_DATFRK;
  473. if (!MacZip.HaveGMToffset) info_flag |= EB_M3_FL_NOUTC;
  474. *ef++ = (char)info_flag;
  475. *ef++ = (char)0x00; /* reserved at the moment */
  476. /* Note: Apple defined File-Type/-Creator as OSType ( =unsigned long,
  477. see Universal Headers 3.1). However, File-Type/-Creator are a
  478. unique four-character sequence. Therefore the byteorder of the
  479. File-Type/-Creator are NOT changed. The native format is used. */
  480. /* Type: 4 Bytes */
  481. *ef++ = (char)(MacZip.fpb.hFileInfo.ioFlFndrInfo.fdType >> 24);
  482. *ef++ = (char)(MacZip.fpb.hFileInfo.ioFlFndrInfo.fdType >> 16);
  483. *ef++ = (char)(MacZip.fpb.hFileInfo.ioFlFndrInfo.fdType >> 8);
  484. *ef++ = (char)(MacZip.fpb.hFileInfo.ioFlFndrInfo.fdType);
  485. /* Creator: 4 Bytes */
  486. *ef++ = (char)(MacZip.fpb.hFileInfo.ioFlFndrInfo.fdCreator >> 24);
  487. *ef++ = (char)(MacZip.fpb.hFileInfo.ioFlFndrInfo.fdCreator >> 16);
  488. *ef++ = (char)(MacZip.fpb.hFileInfo.ioFlFndrInfo.fdCreator >> 8);
  489. *ef++ = (char)(MacZip.fpb.hFileInfo.ioFlFndrInfo.fdCreator);
  490. return ef;
  491. }
  492. /*
  493. * Build the new mac local extra field header.
  494. * All native data are in Intel (=little-endian) format
  495. */
  496. unsigned make_extrafield_MAC3(char *ef)
  497. {
  498. char *ef_m3_begin = ef;
  499. char *temp_Pathname;
  500. char tmp_buffer[NAME_MAX];
  501. unsigned char comment[257];
  502. unsigned short FLength = 0;
  503. unsigned short CLength = 0;
  504. short tempFork;
  505. OSErr err;
  506. Assert_it(ef, "make_extrafield_MAC3","")
  507. if (MacZip.isMacStatValid == false)
  508. {
  509. fprintf(stderr,
  510. "Internal Logic Error: [%d/%s] MacStat is out of sync !",
  511. __LINE__, __FILE__);
  512. exit(-1);
  513. }
  514. /* Start Macintosh Finder FInfo structure except Type/Creator
  515. (see make_EF_Head_MAC3()) 8 Bytes overall */
  516. /* file Finder Flags: 2 Bytes */
  517. *ef++ = (char)(MacZip.fpb.hFileInfo.ioFlFndrInfo.fdFlags);
  518. *ef++ = (char)(MacZip.fpb.hFileInfo.ioFlFndrInfo.fdFlags >> 8);
  519. /* Finders Icon position of a file*/
  520. /* V/Y-Position: 2 Bytes */
  521. *ef++ = (char)(MacZip.fpb.hFileInfo.ioFlFndrInfo.fdLocation.v);
  522. *ef++ = (char)(MacZip.fpb.hFileInfo.ioFlFndrInfo.fdLocation.v >> 8);
  523. /* H/X-Position: 2 Bytes */
  524. *ef++ = (char)(MacZip.fpb.hFileInfo.ioFlFndrInfo.fdLocation.h);
  525. *ef++ = (char)(MacZip.fpb.hFileInfo.ioFlFndrInfo.fdLocation.h >> 8);
  526. /* fdFldr Folder containing file 2 Bytes */
  527. *ef++ = (char)(MacZip.fpb.hFileInfo.ioFlFndrInfo.fdFldr);
  528. *ef++ = (char)(MacZip.fpb.hFileInfo.ioFlFndrInfo.fdFldr >> 8);
  529. /* End Macintosh Finder FInfo structure */
  530. /* 8 Bytes so far ... */
  531. /* Start Macintosh Finder FXInfo structure 16 Bytes overall */
  532. /* Icon ID: 2 Bytes */
  533. *ef++ = (char)(MacZip.fpb.hFileInfo.ioFlXFndrInfo.fdIconID);
  534. *ef++ = (char)(MacZip.fpb.hFileInfo.ioFlXFndrInfo.fdIconID >> 8);
  535. /* unused: 6 Bytes */
  536. *ef++ = (char)(MacZip.fpb.hFileInfo.ioFlXFndrInfo.fdUnused[0]);
  537. *ef++ = (char)(MacZip.fpb.hFileInfo.ioFlXFndrInfo.fdUnused[0] >> 8);
  538. *ef++ = (char)(MacZip.fpb.hFileInfo.ioFlXFndrInfo.fdUnused[1]);
  539. *ef++ = (char)(MacZip.fpb.hFileInfo.ioFlXFndrInfo.fdUnused[1] >> 8);
  540. *ef++ = (char)(MacZip.fpb.hFileInfo.ioFlXFndrInfo.fdUnused[2]);
  541. *ef++ = (char)(MacZip.fpb.hFileInfo.ioFlXFndrInfo.fdUnused[2] >> 8);
  542. /* Script flag: 1 Byte */
  543. *ef++ = (char)(MacZip.fpb.hFileInfo.ioFlXFndrInfo.fdScript);
  544. /* More flag bits: 1 Byte */
  545. *ef++ = (char)(MacZip.fpb.hFileInfo.ioFlXFndrInfo.fdXFlags);
  546. /* Comment ID 2 Bytes */
  547. *ef++ = (char)(MacZip.fpb.hFileInfo.ioFlXFndrInfo.fdComment);
  548. *ef++ = (char)(MacZip.fpb.hFileInfo.ioFlXFndrInfo.fdComment >> 8);
  549. /* Home Dir ID: 4 Bytes */
  550. *ef++ = (char)(MacZip.fpb.hFileInfo.ioFlXFndrInfo.fdPutAway);
  551. *ef++ = (char)(MacZip.fpb.hFileInfo.ioFlXFndrInfo.fdPutAway >> 8);
  552. *ef++ = (char)(MacZip.fpb.hFileInfo.ioFlXFndrInfo.fdPutAway >> 16);
  553. *ef++ = (char)(MacZip.fpb.hFileInfo.ioFlXFndrInfo.fdPutAway >> 24);
  554. /* End Macintosh Finder FXInfo structure */
  555. /* 24 Bytes so far ... */
  556. /* file version number 1 Byte */
  557. *ef++ = (char)(MacZip.fpb.hFileInfo.ioFVersNum);
  558. /* directory access rights 1 Byte */
  559. *ef++ = (char)(MacZip.fpb.hFileInfo.ioACUser);
  560. /* Creation-time 4 Bytes */
  561. *ef++ = (char)(MacZip.fpb.hFileInfo.ioFlCrDat);
  562. *ef++ = (char)(MacZip.fpb.hFileInfo.ioFlCrDat >> 8);
  563. *ef++ = (char)(MacZip.fpb.hFileInfo.ioFlCrDat >> 16);
  564. *ef++ = (char)(MacZip.fpb.hFileInfo.ioFlCrDat >> 24);
  565. /* Modification-time 4 Bytes */
  566. *ef++ = (char)(MacZip.fpb.hFileInfo.ioFlMdDat);
  567. *ef++ = (char)(MacZip.fpb.hFileInfo.ioFlMdDat >> 8);
  568. *ef++ = (char)(MacZip.fpb.hFileInfo.ioFlMdDat >> 16);
  569. *ef++ = (char)(MacZip.fpb.hFileInfo.ioFlMdDat >> 24);
  570. /* Backup-time 4 Bytes */
  571. *ef++ = (char)(MacZip.fpb.hFileInfo.ioFlBkDat);
  572. *ef++ = (char)(MacZip.fpb.hFileInfo.ioFlBkDat >> 8);
  573. *ef++ = (char)(MacZip.fpb.hFileInfo.ioFlBkDat >> 16);
  574. *ef++ = (char)(MacZip.fpb.hFileInfo.ioFlBkDat >> 24);
  575. /* 38 Bytes so far ... */
  576. #ifdef USE_EF_UT_TIME
  577. if (MacZip.HaveGMToffset) {
  578. /* GMT-Offset times 12 Bytes */
  579. *ef++ = (char)(MacZip.Cr_UTCoffs);
  580. *ef++ = (char)(MacZip.Cr_UTCoffs >> 8);
  581. *ef++ = (char)(MacZip.Cr_UTCoffs >> 16);
  582. *ef++ = (char)(MacZip.Cr_UTCoffs >> 24);
  583. *ef++ = (char)(MacZip.Md_UTCoffs);
  584. *ef++ = (char)(MacZip.Md_UTCoffs >> 8);
  585. *ef++ = (char)(MacZip.Md_UTCoffs >> 16);
  586. *ef++ = (char)(MacZip.Md_UTCoffs >> 24);
  587. *ef++ = (char)(MacZip.Bk_UTCoffs);
  588. *ef++ = (char)(MacZip.Bk_UTCoffs >> 8);
  589. *ef++ = (char)(MacZip.Bk_UTCoffs >> 16);
  590. *ef++ = (char)(MacZip.Bk_UTCoffs >> 24);
  591. }
  592. /* 50 Bytes so far ... */
  593. #endif
  594. /* Text Encoding Base (charset) 2 Bytes */
  595. *ef++ = (char)(MacZip.CurrTextEncodingBase);
  596. *ef++ = (char)(MacZip.CurrTextEncodingBase >> 8);
  597. /* 52 Bytes so far ... */
  598. /* MacZip.CurrentFork will be changed, so we have to save it */
  599. tempFork = MacZip.CurrentFork;
  600. if (!MacZip.StoreFullPath) {
  601. temp_Pathname = StripPartialDir(tmp_buffer, MacZip.SearchDir,
  602. MacZip.FullPath);
  603. } else {
  604. temp_Pathname = MacZip.FullPath;
  605. }
  606. MacZip.CurrentFork = tempFork;
  607. FLength = strlen(temp_Pathname) + 1;
  608. memcpy( ef, temp_Pathname, (size_t)FLength );
  609. ef += FLength; /* make room for the string - variable length */
  610. err = FSpLocationFromFullPath(strlen(MacZip.FullPath), MacZip.FullPath,
  611. &MacZip.fileSpec);
  612. printerr("FSpLocationFromFullPath:", err, err,
  613. __LINE__, __FILE__, tmp_buffer);
  614. err = FSpDTGetComment(&MacZip.fileSpec, comment);
  615. printerr("FSpDTGetComment:", (err != -5012) && (err != 0), err,
  616. __LINE__, __FILE__, "");
  617. PToCCpy(comment,tmp_buffer);
  618. CLength = strlen(tmp_buffer) + 1;
  619. memcpy( ef, tmp_buffer, (size_t)CLength );
  620. ef += CLength; /* make room for the string - variable length */
  621. if (verbose) printf("\n comment: [%s]", tmp_buffer);
  622. return (unsigned)(ef - ef_m3_begin);
  623. }
  624. /*
  625. * Print all native data of the new mac local extra field.
  626. * It's for debugging purposes and disabled by default.
  627. */
  628. static void PrintFileInfo(void)
  629. {
  630. DateTimeRec MacTime;
  631. printf("\n\n---------------------------------------------"\
  632. "----------------------------------");
  633. printf("\n FullPath Name = [%s]", MacZip.FullPath);
  634. printf("\n File Attributes = %s 0x%x %d",
  635. sBit2Str(MacZip.fpb.hFileInfo.ioFlAttrib),
  636. MacZip.fpb.hFileInfo.ioFlAttrib,
  637. MacZip.fpb.hFileInfo.ioFlAttrib);
  638. printf("\n Enclosing Folder ID# = 0x%x %d",
  639. MacZip.fpb.hFileInfo.ioFlParID,
  640. MacZip.fpb.hFileInfo.ioFlParID);
  641. if (!MacZip.isDirectory)
  642. {
  643. printf("\n File Type = [%c%c%c%c] 0x%lx",
  644. MacZip.fpb.hFileInfo.ioFlFndrInfo.fdType >> 24,
  645. MacZip.fpb.hFileInfo.ioFlFndrInfo.fdType >> 16,
  646. MacZip.fpb.hFileInfo.ioFlFndrInfo.fdType >> 8,
  647. MacZip.fpb.hFileInfo.ioFlFndrInfo.fdType,
  648. MacZip.fpb.hFileInfo.ioFlFndrInfo.fdType);
  649. printf("\n File Creator = [%c%c%c%c] 0x%lx",
  650. MacZip.fpb.hFileInfo.ioFlFndrInfo.fdCreator >> 24,
  651. MacZip.fpb.hFileInfo.ioFlFndrInfo.fdCreator >> 16,
  652. MacZip.fpb.hFileInfo.ioFlFndrInfo.fdCreator >> 8,
  653. MacZip.fpb.hFileInfo.ioFlFndrInfo.fdCreator,
  654. MacZip.fpb.hFileInfo.ioFlFndrInfo.fdCreator);
  655. printf("\n Data Fork :" );
  656. printf("\n Actual (Logical) Length = %d 0x%x ",
  657. MacZip.fpb.hFileInfo.ioFlLgLen,
  658. MacZip.fpb.hFileInfo.ioFlLgLen);
  659. printf("\n Allocated (Physical) Length = %d 0x%x",
  660. MacZip.fpb.hFileInfo.ioFlPyLen,
  661. MacZip.fpb.hFileInfo.ioFlPyLen);
  662. printf("\n Resource Fork :" );
  663. printf("\n Actual (Logical) Length = %d 0x%x",
  664. MacZip.fpb.hFileInfo.ioFlRLgLen,
  665. MacZip.fpb.hFileInfo.ioFlRLgLen );
  666. printf("\n Allocated (Physical) Length = %d 0x%x",
  667. MacZip.fpb.hFileInfo.ioFlRPyLen,
  668. MacZip.fpb.hFileInfo.ioFlRPyLen );
  669. }
  670. printf("\n Dates : ");
  671. SecondsToDate (MacZip.CreatDate, &MacTime);
  672. printf("\n Created = %4d/%2d/%2d %2d:%2d:%2d ",
  673. MacTime.year,
  674. MacTime.month,
  675. MacTime.day,
  676. MacTime.hour,
  677. MacTime.minute,
  678. MacTime.second);
  679. SecondsToDate (MacZip.BackDate, &MacTime);
  680. printf("\n Backup = %4d/%2d/%2d %2d:%2d:%2d ",
  681. MacTime.year,
  682. MacTime.month,
  683. MacTime.day,
  684. MacTime.hour,
  685. MacTime.minute,
  686. MacTime.second);
  687. SecondsToDate (MacZip.ModDate, &MacTime);
  688. printf("\n Modified = %4d/%2d/%2d %2d:%2d:%2d ",
  689. MacTime.year,
  690. MacTime.month,
  691. MacTime.day,
  692. MacTime.hour,
  693. MacTime.minute,
  694. MacTime.second);
  695. if (!MacZip.isDirectory)
  696. {
  697. printf("\n Finder Flags : %s 0x%x %d",
  698. sBit2Str(MacZip.fpb.hFileInfo.ioFlFndrInfo.fdFlags),
  699. MacZip.fpb.hFileInfo.ioFlFndrInfo.fdFlags,
  700. MacZip.fpb.hFileInfo.ioFlFndrInfo.fdFlags);
  701. printf("\n Finder Icon Position = X: %d 0x%x ",
  702. MacZip.fpb.hFileInfo.ioFlFndrInfo.fdLocation.h,
  703. MacZip.fpb.hFileInfo.ioFlFndrInfo.fdLocation.h);
  704. printf("\n Y: %d 0x%x ",
  705. MacZip.fpb.hFileInfo.ioFlFndrInfo.fdLocation.v,
  706. MacZip.fpb.hFileInfo.ioFlFndrInfo.fdLocation.v);
  707. }
  708. else
  709. {
  710. printf("\n Finder Flags : %s 0x%x %d",
  711. sBit2Str(MacZip.fpb.dirInfo.ioDrUsrWds.frFlags),
  712. MacZip.fpb.dirInfo.ioDrUsrWds.frFlags,
  713. MacZip.fpb.dirInfo.ioDrUsrWds.frFlags);
  714. printf("\n Finder Icon Position = X: %d 0x%x ",
  715. MacZip.fpb.dirInfo.ioDrUsrWds.frLocation.h,
  716. MacZip.fpb.dirInfo.ioDrUsrWds.frLocation.h);
  717. printf("\n Y: %d 0x%x ",
  718. MacZip.fpb.dirInfo.ioDrUsrWds.frLocation.v,
  719. MacZip.fpb.dirInfo.ioDrUsrWds.frLocation.v);
  720. }
  721. printf("\n----------------------------------------------------"\
  722. "---------------------------\n");
  723. }
  724. /*
  725. * If the switch '-v' is used, print some more info.
  726. */
  727. static void print_extra_info(void)
  728. {
  729. char Fork[20];
  730. if (MacZip.CurrentFork == DataFork) sstrcpy(Fork,"<DataFork>");
  731. else sstrcpy(Fork,"<ResourceFork>");
  732. printf("\n%16s [%c%c%c%c] [%c%c%c%c]",Fork,
  733. MacZip.fpb.hFileInfo.ioFlFndrInfo.fdType >> 24,
  734. MacZip.fpb.hFileInfo.ioFlFndrInfo.fdType >> 16,
  735. MacZip.fpb.hFileInfo.ioFlFndrInfo.fdType >> 8,
  736. MacZip.fpb.hFileInfo.ioFlFndrInfo.fdType,
  737. MacZip.fpb.hFileInfo.ioFlFndrInfo.fdCreator >> 24,
  738. MacZip.fpb.hFileInfo.ioFlFndrInfo.fdCreator >> 16,
  739. MacZip.fpb.hFileInfo.ioFlFndrInfo.fdCreator >> 8,
  740. MacZip.fpb.hFileInfo.ioFlFndrInfo.fdCreator);
  741. }