Details | Last modification | View Log | RSS feed
Rev | Author | Line No. | Line |
---|---|---|---|
6725 | siemargl | 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 |
||
25 | #include |
||
26 | #include |
||
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 | } |