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
UZmacstat(const char * path,struct stat * buf)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