diff options
Diffstat (limited to 'macos/source/unixlike.c')
-rw-r--r-- | macos/source/unixlike.c | 313 |
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; +} |