unixlike.c 9.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313
  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. unixlike.c
  10. Macintosh-specific routines to emulate unixfunctions.
  11. ---------------------------------------------------------------------------*/
  12. /*****************************************************************************/
  13. /* Includes */
  14. /*****************************************************************************/
  15. #include "zip.h"
  16. #include <string.h>
  17. #include <stdio.h>
  18. #include <sound.h>
  19. #include "unixlike.h"
  20. #include "helpers.h"
  21. #include "pathname.h"
  22. #include "macstuff.h"
  23. #include "macglob.h"
  24. #include "mactime.h"
  25. /*****************************************************************************/
  26. /* Global Vars */
  27. /*****************************************************************************/
  28. extern MacZipGlobals MacZip;
  29. extern int errno;
  30. /*****************************************************************************/
  31. /* Prototypes */
  32. /*****************************************************************************/
  33. /*****************************************************************************/
  34. /* Functions */
  35. /*****************************************************************************/
  36. /*
  37. *----------------------------------------------------------------------
  38. *
  39. * MacStat --
  40. *
  41. * This function replaces the library version of stat. The stat
  42. * function provided by most Mac compiliers is rather broken and
  43. * incomplete.
  44. *
  45. * Results:
  46. * See stat documentation.
  47. *
  48. * Side effects:
  49. * See stat documentation.
  50. *
  51. *----------------------------------------------------------------------
  52. */
  53. int Zmacstat(const char *Fname, struct stat *buf)
  54. {
  55. OSErr err, rc;
  56. short fullPathLength;
  57. Handle hFullPath;
  58. char path[NAME_MAX], path2[NAME_MAX];
  59. HVolumeParam vpb;
  60. static unsigned long count_of_files = 0;
  61. AssertStr(Fname,Fname)
  62. Assert_it(buf,"","")
  63. UserStop();
  64. memset(buf, 0, sizeof(buf)); /* zero out all fields */
  65. RfDfFilen2Real(path2, Fname, MacZip.MacZipMode, MacZip.DataForkOnly,
  66. &MacZip.CurrentFork);
  67. GetCompletePath(path, path2, &MacZip.fileSpec, &err);
  68. err = PrintUserHFSerr((err != -43) && (err != 0), err, path);
  69. printerr("GetCompletePath:", err, err, __LINE__, __FILE__, path);
  70. if (err != noErr) {
  71. errno = err;
  72. return -1;
  73. }
  74. /* Collect here some more information, it's not related to Macstat.
  75. (note: filespec gets changed later in this function) */
  76. /* clear string-buffer */
  77. memset(MacZip.FullPath, 0x00, sizeof(MacZip.FullPath));
  78. rc = FSpGetFullPath(&MacZip.fileSpec, &fullPathLength, &hFullPath);
  79. strncpy(MacZip.FullPath, *hFullPath, fullPathLength);
  80. DisposeHandle(hFullPath); /* we don't need it any more */
  81. /* Collect some more information not related to Macstat */
  82. /*
  83. * Fill the fpb & vpb struct up with info about file or directory.
  84. */
  85. FSpGetDirectoryID(&MacZip.fileSpec, &MacZip.dirID, &MacZip.isDirectory);
  86. vpb.ioVRefNum = MacZip.fpb.hFileInfo.ioVRefNum = MacZip.fileSpec.vRefNum;
  87. vpb.ioNamePtr = MacZip.fpb.hFileInfo.ioNamePtr = MacZip.fileSpec.name;
  88. if (MacZip.isDirectory) {
  89. MacZip.fpb.hFileInfo.ioDirID = MacZip.fileSpec.parID;
  90. /*
  91. * Directories are executable by everyone.
  92. */
  93. buf->st_mode |= UNX_IXUSR | UNX_IXGRP | UNX_IXOTH | UNX_IFDIR;
  94. } else {
  95. MacZip.fpb.hFileInfo.ioDirID = MacZip.dirID;
  96. }
  97. MacZip.fpb.hFileInfo.ioFDirIndex = 0;
  98. err = PBGetCatInfoSync((CInfoPBPtr)&MacZip.fpb);
  99. if (err == noErr) {
  100. vpb.ioVolIndex = 0;
  101. err = PBHGetVInfoSync((HParmBlkPtr)&vpb);
  102. if (err == noErr && buf != NULL) {
  103. /*
  104. * Files are always readable by everyone.
  105. */
  106. buf->st_mode |= UNX_IRUSR | UNX_IRGRP | UNX_IROTH;
  107. /*
  108. * Use the Volume Info & File Info to fill out stat buf.
  109. */
  110. if (MacZip.fpb.hFileInfo.ioFlAttrib & 0x10) {
  111. buf->st_mode |= UNX_IFDIR;
  112. buf->st_nlink = 2;
  113. } else {
  114. buf->st_nlink = 1;
  115. if (MacZip.fpb.hFileInfo.ioFlFndrInfo.fdFlags & 0x8000) {
  116. buf->st_mode |= UNX_IFLNK;
  117. } else {
  118. buf->st_mode |= UNX_IFREG;
  119. }
  120. }
  121. if (MacZip.fpb.hFileInfo.ioFlFndrInfo.fdType == 'APPL') {
  122. /*
  123. * Applications are executable by everyone.
  124. */
  125. buf->st_mode |= UNX_IXUSR | UNX_IXGRP | UNX_IXOTH;
  126. }
  127. if ((MacZip.fpb.hFileInfo.ioFlAttrib & 0x01) == 0){
  128. /*
  129. * If not locked, then everyone has write acces.
  130. */
  131. buf->st_mode |= UNX_IWUSR | UNX_IWGRP | UNX_IWOTH;
  132. }
  133. buf->st_ino = MacZip.fpb.hFileInfo.ioDirID;
  134. buf->st_dev = MacZip.fpb.hFileInfo.ioVRefNum;
  135. buf->st_uid = -1;
  136. buf->st_gid = -1;
  137. buf->st_rdev = 0;
  138. if (MacZip.CurrentFork == ResourceFork)
  139. buf->st_size = MacZip.fpb.hFileInfo.ioFlRLgLen;
  140. else
  141. buf->st_size = MacZip.fpb.hFileInfo.ioFlLgLen;
  142. buf->st_blksize = vpb.ioVAlBlkSiz;
  143. buf->st_blocks = (buf->st_size + buf->st_blksize - 1)
  144. / buf->st_blksize;
  145. /*
  146. * The times returned by the Mac file system are in the
  147. * local time zone. We convert them to GMT so that the
  148. * epoch starts from GMT. This is also consistent with
  149. * what is returned from "clock seconds".
  150. */
  151. if (!MacZip.isDirectory) {
  152. MacZip.CreatDate = MacZip.fpb.hFileInfo.ioFlCrDat;
  153. MacZip.ModDate = MacZip.fpb.hFileInfo.ioFlMdDat;
  154. MacZip.BackDate = MacZip.fpb.hFileInfo.ioFlBkDat;
  155. } else {
  156. MacZip.CreatDate = MacZip.fpb.dirInfo.ioDrCrDat;
  157. MacZip.ModDate = MacZip.fpb.dirInfo.ioDrMdDat;
  158. MacZip.BackDate = MacZip.fpb.dirInfo.ioDrBkDat;
  159. }
  160. #ifdef IZ_CHECK_TZ
  161. if (!zp_tz_is_valid)
  162. {
  163. MacZip.HaveGMToffset = false;
  164. MacZip.Md_UTCoffs = 0L;
  165. MacZip.Cr_UTCoffs = 0L;
  166. MacZip.Bk_UTCoffs = 0L;
  167. }
  168. else
  169. #endif
  170. {
  171. /* Do not use GMT offsets when Md_UTCoffs calculation
  172. * fails, since this time stamp is used for time
  173. * comparisons in Zip and UnZip operations.
  174. * We do not bother when GMT offset calculation fails for
  175. * any other time stamp value. Instead we simply assume
  176. * a default value of 0.
  177. */
  178. MacZip.HaveGMToffset =
  179. GetGMToffsetMac(MacZip.ModDate, &MacZip.Md_UTCoffs);
  180. if (MacZip.HaveGMToffset) {
  181. GetGMToffsetMac(MacZip.CreatDate, &MacZip.Cr_UTCoffs);
  182. GetGMToffsetMac(MacZip.BackDate, &MacZip.Bk_UTCoffs);
  183. } else {
  184. MacZip.Cr_UTCoffs = 0L;
  185. MacZip.Bk_UTCoffs = 0L;
  186. }
  187. }
  188. #ifdef DEBUG_TIME
  189. {
  190. printf("\nZmacstat: MacZip.HaveGMToffset: %d",
  191. MacZip.HaveGMToffset);
  192. printf("\nZmacstat: Mac modif: %lu local -> UTOffset: %d",
  193. MacZip.ModDate, MacZip.Md_UTCoffs);
  194. printf("\nZmacstat: Mac creat: %lu local -> UTOffset: %d",
  195. MacZip.CreatDate, MacZip.Cr_UTCoffs);
  196. printf("\nZmacstat: Mac back: %lu local -> UTOffset: %d",
  197. MacZip.BackDate, MacZip.Bk_UTCoffs);
  198. }
  199. #endif /* DEBUG_TIME */
  200. buf->st_mtime = MacFtime2UnixFtime(MacZip.ModDate);
  201. buf->st_ctime = MacFtime2UnixFtime(MacZip.CreatDate);
  202. buf->st_atime = buf->st_mtime;
  203. #ifdef DEBUG_TIME
  204. {
  205. printf("\nZmacstat: Unix modif: %lu UTC; Mac: %lu local",
  206. buf->st_mtime, MacZip.ModDate);
  207. printf("\nZmacstat: Unix creat: %lu UTC; Mac: %lu local\n",
  208. buf->st_ctime, MacZip.CreatDate);
  209. }
  210. #endif /* DEBUG_TIME */
  211. if (noisy)
  212. {
  213. if (MacZip.StatingProgress)
  214. {
  215. count_of_files++;
  216. InformProgress(MacZip.RawCountOfItems, count_of_files );
  217. }
  218. else
  219. count_of_files = 0;
  220. }
  221. }
  222. }
  223. if (err != noErr) {
  224. errno = err;
  225. }
  226. MacZip.isMacStatValid = true;
  227. return (err == noErr ? 0 : -1);
  228. }
  229. /*
  230. *----------------------------------------------------------------------
  231. *
  232. * chmod --
  233. *
  234. * Results:
  235. * See chmod documentation.
  236. *
  237. * Side effects:
  238. * See chmod documentation.
  239. *
  240. *----------------------------------------------------------------------
  241. */
  242. int chmod(char *path, int mode)
  243. {
  244. HParamBlockRec hpb;
  245. OSErr err;
  246. hpb.fileParam.ioNamePtr = C2PStr(path);
  247. hpb.fileParam.ioVRefNum = 0;
  248. hpb.fileParam.ioDirID = 0;
  249. if (mode & 0200) {
  250. err = PBHRstFLockSync(&hpb);
  251. } else {
  252. err = PBHSetFLockSync(&hpb);
  253. }
  254. if (err != noErr) {
  255. errno = err;
  256. return -1;
  257. }
  258. return 0;
  259. }