summaryrefslogtreecommitdiff
path: root/macos/source/unixlike.c
diff options
context:
space:
mode:
Diffstat (limited to 'macos/source/unixlike.c')
-rw-r--r--macos/source/unixlike.c313
1 files changed, 313 insertions, 0 deletions
diff --git a/macos/source/unixlike.c b/macos/source/unixlike.c
new file mode 100644
index 0000000..017d3fa
--- /dev/null
+++ b/macos/source/unixlike.c
@@ -0,0 +1,313 @@
+/*
+ Copyright (c) 1990-2005 Info-ZIP. All rights reserved.
+
+ See the accompanying file LICENSE, version 2004-May-22 or later
+ (the contents of which are also included in zip.h) for terms of use.
+ If, for some reason, both of these files are missing, the Info-ZIP license
+ also may be found at: ftp://ftp.info-zip.org/pub/infozip/license.html
+*/
+/*---------------------------------------------------------------------------
+
+ unixlike.c
+
+ Macintosh-specific routines to emulate unixfunctions.
+
+ ---------------------------------------------------------------------------*/
+
+/*****************************************************************************/
+/* Includes */
+/*****************************************************************************/
+
+#include "zip.h"
+
+#include <string.h>
+#include <stdio.h>
+#include <sound.h>
+
+#include "unixlike.h"
+#include "helpers.h"
+#include "pathname.h"
+#include "macstuff.h"
+#include "macglob.h"
+#include "mactime.h"
+
+/*****************************************************************************/
+/* Global Vars */
+/*****************************************************************************/
+
+extern MacZipGlobals MacZip;
+extern int errno;
+
+
+/*****************************************************************************/
+/* Prototypes */
+/*****************************************************************************/
+
+
+/*****************************************************************************/
+/* Functions */
+/*****************************************************************************/
+
+
+
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * MacStat --
+ *
+ * This function replaces the library version of stat. The stat
+ * function provided by most Mac compiliers is rather broken and
+ * incomplete.
+ *
+ * Results:
+ * See stat documentation.
+ *
+ * Side effects:
+ * See stat documentation.
+ *
+ *----------------------------------------------------------------------
+ */
+
+int Zmacstat(const char *Fname, struct stat *buf)
+{
+ OSErr err, rc;
+ short fullPathLength;
+ Handle hFullPath;
+ char path[NAME_MAX], path2[NAME_MAX];
+ HVolumeParam vpb;
+ static unsigned long count_of_files = 0;
+
+ AssertStr(Fname,Fname)
+ Assert_it(buf,"","")
+
+ UserStop();
+
+ memset(buf, 0, sizeof(buf)); /* zero out all fields */
+
+ RfDfFilen2Real(path2, Fname, MacZip.MacZipMode, MacZip.DataForkOnly,
+ &MacZip.CurrentFork);
+ GetCompletePath(path, path2, &MacZip.fileSpec, &err);
+ err = PrintUserHFSerr((err != -43) && (err != 0), err, path);
+ printerr("GetCompletePath:", err, err, __LINE__, __FILE__, path);
+
+ if (err != noErr) {
+ errno = err;
+ return -1;
+ }
+
+ /* Collect here some more information, it's not related to Macstat.
+ (note: filespec gets changed later in this function) */
+ /* clear string-buffer */
+ memset(MacZip.FullPath, 0x00, sizeof(MacZip.FullPath));
+ rc = FSpGetFullPath(&MacZip.fileSpec, &fullPathLength, &hFullPath);
+ strncpy(MacZip.FullPath, *hFullPath, fullPathLength);
+ DisposeHandle(hFullPath); /* we don't need it any more */
+ /* Collect some more information not related to Macstat */
+
+
+ /*
+ * Fill the fpb & vpb struct up with info about file or directory.
+ */
+
+ FSpGetDirectoryID(&MacZip.fileSpec, &MacZip.dirID, &MacZip.isDirectory);
+ vpb.ioVRefNum = MacZip.fpb.hFileInfo.ioVRefNum = MacZip.fileSpec.vRefNum;
+ vpb.ioNamePtr = MacZip.fpb.hFileInfo.ioNamePtr = MacZip.fileSpec.name;
+
+ if (MacZip.isDirectory) {
+ MacZip.fpb.hFileInfo.ioDirID = MacZip.fileSpec.parID;
+ /*
+ * Directories are executable by everyone.
+ */
+ buf->st_mode |= UNX_IXUSR | UNX_IXGRP | UNX_IXOTH | UNX_IFDIR;
+ } else {
+ MacZip.fpb.hFileInfo.ioDirID = MacZip.dirID;
+ }
+
+ MacZip.fpb.hFileInfo.ioFDirIndex = 0;
+ err = PBGetCatInfoSync((CInfoPBPtr)&MacZip.fpb);
+
+ if (err == noErr) {
+ vpb.ioVolIndex = 0;
+ err = PBHGetVInfoSync((HParmBlkPtr)&vpb);
+ if (err == noErr && buf != NULL) {
+ /*
+ * Files are always readable by everyone.
+ */
+ buf->st_mode |= UNX_IRUSR | UNX_IRGRP | UNX_IROTH;
+
+ /*
+ * Use the Volume Info & File Info to fill out stat buf.
+ */
+ if (MacZip.fpb.hFileInfo.ioFlAttrib & 0x10) {
+ buf->st_mode |= UNX_IFDIR;
+ buf->st_nlink = 2;
+ } else {
+ buf->st_nlink = 1;
+ if (MacZip.fpb.hFileInfo.ioFlFndrInfo.fdFlags & 0x8000) {
+ buf->st_mode |= UNX_IFLNK;
+ } else {
+ buf->st_mode |= UNX_IFREG;
+ }
+ }
+
+ if (MacZip.fpb.hFileInfo.ioFlFndrInfo.fdType == 'APPL') {
+ /*
+ * Applications are executable by everyone.
+ */
+ buf->st_mode |= UNX_IXUSR | UNX_IXGRP | UNX_IXOTH;
+ }
+ if ((MacZip.fpb.hFileInfo.ioFlAttrib & 0x01) == 0){
+ /*
+ * If not locked, then everyone has write acces.
+ */
+ buf->st_mode |= UNX_IWUSR | UNX_IWGRP | UNX_IWOTH;
+ }
+
+ buf->st_ino = MacZip.fpb.hFileInfo.ioDirID;
+ buf->st_dev = MacZip.fpb.hFileInfo.ioVRefNum;
+ buf->st_uid = -1;
+ buf->st_gid = -1;
+ buf->st_rdev = 0;
+
+ if (MacZip.CurrentFork == ResourceFork)
+ buf->st_size = MacZip.fpb.hFileInfo.ioFlRLgLen;
+ else
+ buf->st_size = MacZip.fpb.hFileInfo.ioFlLgLen;
+
+ buf->st_blksize = vpb.ioVAlBlkSiz;
+ buf->st_blocks = (buf->st_size + buf->st_blksize - 1)
+ / buf->st_blksize;
+
+ /*
+ * The times returned by the Mac file system are in the
+ * local time zone. We convert them to GMT so that the
+ * epoch starts from GMT. This is also consistent with
+ * what is returned from "clock seconds".
+ */
+ if (!MacZip.isDirectory) {
+ MacZip.CreatDate = MacZip.fpb.hFileInfo.ioFlCrDat;
+ MacZip.ModDate = MacZip.fpb.hFileInfo.ioFlMdDat;
+ MacZip.BackDate = MacZip.fpb.hFileInfo.ioFlBkDat;
+ } else {
+ MacZip.CreatDate = MacZip.fpb.dirInfo.ioDrCrDat;
+ MacZip.ModDate = MacZip.fpb.dirInfo.ioDrMdDat;
+ MacZip.BackDate = MacZip.fpb.dirInfo.ioDrBkDat;
+ }
+
+#ifdef IZ_CHECK_TZ
+ if (!zp_tz_is_valid)
+ {
+ MacZip.HaveGMToffset = false;
+ MacZip.Md_UTCoffs = 0L;
+ MacZip.Cr_UTCoffs = 0L;
+ MacZip.Bk_UTCoffs = 0L;
+ }
+ else
+#endif
+ {
+ /* Do not use GMT offsets when Md_UTCoffs calculation
+ * fails, since this time stamp is used for time
+ * comparisons in Zip and UnZip operations.
+ * We do not bother when GMT offset calculation fails for
+ * any other time stamp value. Instead we simply assume
+ * a default value of 0.
+ */
+ MacZip.HaveGMToffset =
+ GetGMToffsetMac(MacZip.ModDate, &MacZip.Md_UTCoffs);
+ if (MacZip.HaveGMToffset) {
+ GetGMToffsetMac(MacZip.CreatDate, &MacZip.Cr_UTCoffs);
+ GetGMToffsetMac(MacZip.BackDate, &MacZip.Bk_UTCoffs);
+ } else {
+ MacZip.Cr_UTCoffs = 0L;
+ MacZip.Bk_UTCoffs = 0L;
+ }
+ }
+#ifdef DEBUG_TIME
+ {
+ printf("\nZmacstat: MacZip.HaveGMToffset: %d",
+ MacZip.HaveGMToffset);
+ printf("\nZmacstat: Mac modif: %lu local -> UTOffset: %d",
+ MacZip.ModDate, MacZip.Md_UTCoffs);
+ printf("\nZmacstat: Mac creat: %lu local -> UTOffset: %d",
+ MacZip.CreatDate, MacZip.Cr_UTCoffs);
+ printf("\nZmacstat: Mac back: %lu local -> UTOffset: %d",
+ MacZip.BackDate, MacZip.Bk_UTCoffs);
+ }
+#endif /* DEBUG_TIME */
+
+
+ buf->st_mtime = MacFtime2UnixFtime(MacZip.ModDate);
+ buf->st_ctime = MacFtime2UnixFtime(MacZip.CreatDate);
+ buf->st_atime = buf->st_mtime;
+
+#ifdef DEBUG_TIME
+ {
+ printf("\nZmacstat: Unix modif: %lu UTC; Mac: %lu local",
+ buf->st_mtime, MacZip.ModDate);
+ printf("\nZmacstat: Unix creat: %lu UTC; Mac: %lu local\n",
+ buf->st_ctime, MacZip.CreatDate);
+ }
+#endif /* DEBUG_TIME */
+
+ if (noisy)
+ {
+ if (MacZip.StatingProgress)
+ {
+ count_of_files++;
+ InformProgress(MacZip.RawCountOfItems, count_of_files );
+ }
+ else
+ count_of_files = 0;
+ }
+ }
+ }
+
+ if (err != noErr) {
+ errno = err;
+ }
+
+ MacZip.isMacStatValid = true;
+ return (err == noErr ? 0 : -1);
+}
+
+
+
+
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * chmod --
+ *
+ * Results:
+ * See chmod documentation.
+ *
+ * Side effects:
+ * See chmod documentation.
+ *
+ *----------------------------------------------------------------------
+ */
+
+int chmod(char *path, int mode)
+{
+ HParamBlockRec hpb;
+ OSErr err;
+
+ hpb.fileParam.ioNamePtr = C2PStr(path);
+ hpb.fileParam.ioVRefNum = 0;
+ hpb.fileParam.ioDirID = 0;
+
+ if (mode & 0200) {
+ err = PBHRstFLockSync(&hpb);
+ } else {
+ err = PBHSetFLockSync(&hpb);
+ }
+
+ if (err != noErr) {
+ errno = err;
+ return -1;
+ }
+
+ return 0;
+}