Subversion Repositories Kolibri OS

Rev

Blame | Last modification | View Log | Download | RSS feed

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