PageRenderTime 94ms CodeModel.GetById 24ms RepoModel.GetById 0ms app.codeStats 1ms

/src/boinc/boinc/zip/zip/macos/source/extrafld.c

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