macstat.c 6.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188
  1. /*
  2. Copyright (c) 1990-2003 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 unzip.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. macstat.c
  10. * This file provides a unix like file-stat routine
  11. * for V7 Unix systems that don't have such procedures.
  12. *
  13. *
  14. ---------------------------------------------------------------------------*/
  15. /*****************************************************************************/
  16. /* Includes */
  17. /*****************************************************************************/
  18. #include <string.h>
  19. #include <stdio.h>
  20. #include <sound.h>
  21. #define UNZIP_INTERNAL
  22. #include "unzip.h"
  23. #include "macstat.h"
  24. #include "helpers.h"
  25. #include "pathname.h"
  26. #include "macstuff.h"
  27. #include "mactime.h"
  28. /*****************************************************************************/
  29. /* Global Vars */
  30. /*****************************************************************************/
  31. extern int errno;
  32. extern MACINFO newExtraField; /* contains all extra-field data */
  33. extern short MacZipMode;
  34. /*****************************************************************************/
  35. /* Prototypes */
  36. /*****************************************************************************/
  37. /*****************************************************************************/
  38. /* Functions */
  39. /*****************************************************************************/
  40. int UZmacstat(const char *path, struct stat *buf)
  41. {
  42. Boolean isDirectory;
  43. long dirID;
  44. char fullpath[NAME_MAX], UnmangledPath[NAME_MAX];
  45. CInfoPBRec fpb;
  46. HVolumeParam vpb;
  47. FSSpec fileSpec;
  48. OSErr err, err2;
  49. short CurrentFork;
  50. AssertStr(path,path)
  51. Assert_it(buf,"","")
  52. memset(buf, 0, sizeof(struct stat)); /* zero out all fields */
  53. RfDfFilen2Real(UnmangledPath, path, MacZipMode,
  54. (newExtraField.flags & EB_M3_FL_NOCHANGE), &CurrentFork);
  55. GetCompletePath(fullpath, path, &fileSpec, &err);
  56. err2 = PrintUserHFSerr((err != -43) && (err != 0) && (err != -120),
  57. err, path);
  58. printerr("GetCompletePath:", err2, err2, __LINE__, __FILE__, path);
  59. if (err != noErr) {
  60. errno = err;
  61. return -1;
  62. }
  63. /*
  64. * Fill the fpb & vpb struct up with info about file or directory.
  65. */
  66. FSpGetDirectoryID(&fileSpec, &dirID, &isDirectory);
  67. vpb.ioVRefNum = fpb.hFileInfo.ioVRefNum = fileSpec.vRefNum;
  68. vpb.ioNamePtr = fpb.hFileInfo.ioNamePtr = fileSpec.name;
  69. if (isDirectory) {
  70. fpb.hFileInfo.ioDirID = fileSpec.parID;
  71. } else {
  72. fpb.hFileInfo.ioDirID = dirID;
  73. }
  74. fpb.hFileInfo.ioFDirIndex = 0;
  75. err = PBGetCatInfo(&fpb, false);
  76. if (err == noErr) {
  77. vpb.ioVolIndex = 0;
  78. err = PBHGetVInfoSync((HParmBlkPtr)&vpb);
  79. if (err == noErr && buf != NULL) {
  80. /*
  81. * Files are always readable by everyone.
  82. */
  83. buf->st_mode |= S_IRUSR | S_IRGRP | S_IROTH;
  84. /*
  85. * Use the Volume Info & File Info to fill out stat buf.
  86. */
  87. if (fpb.hFileInfo.ioFlAttrib & 0x10) {
  88. buf->st_mode |= S_IFDIR;
  89. buf->st_nlink = 2;
  90. } else {
  91. buf->st_nlink = 1;
  92. if (fpb.hFileInfo.ioFlFndrInfo.fdFlags & 0x8000) {
  93. buf->st_mode |= S_IFLNK;
  94. } else {
  95. buf->st_mode |= S_IFREG;
  96. }
  97. }
  98. if ((fpb.hFileInfo.ioFlAttrib & 0x10) ||
  99. (fpb.hFileInfo.ioFlFndrInfo.fdType == 'APPL')) {
  100. /*
  101. * Directories and applications are executable by everyone.
  102. */
  103. buf->st_mode |= S_IXUSR | S_IXGRP | S_IXOTH;
  104. }
  105. if ((fpb.hFileInfo.ioFlAttrib & 0x01) == 0) {
  106. /*
  107. * If not locked, then everyone has write acces.
  108. */
  109. buf->st_mode |= S_IWUSR | S_IWGRP | S_IWOTH;
  110. }
  111. buf->st_ino = fpb.hFileInfo.ioDirID;
  112. buf->st_dev = fpb.hFileInfo.ioVRefNum;
  113. buf->st_uid = -1;
  114. buf->st_gid = -1;
  115. buf->st_rdev = 0;
  116. if (CurrentFork == ResourceFork)
  117. buf->st_size = fpb.hFileInfo.ioFlRLgLen;
  118. else
  119. buf->st_size = fpb.hFileInfo.ioFlLgLen;
  120. buf->st_blksize = vpb.ioVAlBlkSiz;
  121. buf->st_blocks = (buf->st_size + buf->st_blksize - 1)
  122. / buf->st_blksize;
  123. /*
  124. * The times returned by the Mac file system are in the
  125. * local time zone. We convert them to GMT so that the
  126. * epoch starts from GMT. This is also consistent with
  127. * what is returned from "clock seconds".
  128. */
  129. buf->st_mtime = MacFtime2UnixFtime(fpb.hFileInfo.ioFlMdDat);
  130. buf->st_ctime = MacFtime2UnixFtime(fpb.hFileInfo.ioFlCrDat);
  131. buf->st_atime = buf->st_ctime; /* best guess */
  132. #ifdef DEBUG_TIME
  133. {
  134. struct tm *tp = localtime(&buf->st_mtime);
  135. printf(
  136. "\nUZmacstat: local buf->st_mtime is %ld = %d/%2d/%2d %2d:%2d:%2d",
  137. buf->st_mtime, tp->tm_year, tp->tm_mon+1, tp->tm_mday,
  138. tp->tm_hour, tp->tm_min, tp->tm_sec);
  139. tp = gmtime(&buf->st_mtime);
  140. printf(
  141. "\nUZmacstat: UTC buf->st_mtime is %ld = %d/%2d/%2d %2d:%2d:%2d\n",
  142. buf->st_mtime, tp->tm_year, tp->tm_mon+1, tp->tm_mday,
  143. tp->tm_hour, tp->tm_min, tp->tm_sec);
  144. }
  145. #endif /* DEBUG_TIME */
  146. }
  147. }
  148. if (err != noErr) {
  149. errno = err;
  150. }
  151. return (err == noErr ? 0 : -1);
  152. }