1 | |
2 | |
3 | |
4 | |
5 | |
6 | |
7 | |
8 | |
9 | |
10 | |
11 | |
12 | |
13 | |
14 | |
15 | |
16 | |
17 | #include "apr_arch_file_io.h" |
18 | #include "apr_file_io.h" |
19 | #include "apr_general.h" |
20 | #include "apr_strings.h" |
21 | #include "apr_errno.h" |
22 | |
23 | #ifdef HAVE_UTIME1 |
24 | #include <utime.h> |
25 | #endif |
26 | |
27 | static apr_filetype_e filetype_from_mode(mode_t mode) |
28 | { |
29 | apr_filetype_e type; |
30 | |
31 | switch (mode & S_IFMT0170000) { |
32 | case S_IFREG0100000: |
33 | type = APR_REG; break; |
34 | case S_IFDIR0040000: |
35 | type = APR_DIR; break; |
36 | case S_IFLNK0120000: |
37 | type = APR_LNK; break; |
38 | case S_IFCHR0020000: |
39 | type = APR_CHR; break; |
40 | case S_IFBLK0060000: |
41 | type = APR_BLK; break; |
42 | #if defined(S_IFFIFO) |
43 | case S_IFFIFO: |
44 | type = APR_PIPE; break; |
45 | #endif |
46 | #if !defined(BEOS) && defined(S_IFSOCK0140000) |
47 | case S_IFSOCK0140000: |
48 | type = APR_SOCK; break; |
49 | #endif |
50 | |
51 | default: |
52 | |
53 | |
54 | |
55 | #if !defined(S_IFFIFO) && defined(S_ISFIFO) |
56 | if (S_ISFIFO(mode)((((mode)) & 0170000) == (0010000))) { |
57 | type = APR_PIPE; |
58 | } else |
59 | #endif |
60 | #if !defined(BEOS) && !defined(S_IFSOCK0140000) && defined(S_ISSOCK) |
61 | if (S_ISSOCK(mode)((((mode)) & 0170000) == (0140000))) { |
62 | type = APR_SOCK; |
63 | } else |
64 | #endif |
65 | type = APR_UNKFILE; |
66 | } |
67 | return type; |
68 | } |
69 | |
70 | static void fill_out_finfo(apr_finfo_t *finfo, struct_stat *info, |
71 | apr_int32_t wanted) |
72 | { |
73 | finfo->valid = APR_FINFO_MIN0x00008170 | APR_FINFO_IDENT0x00003000 | APR_FINFO_NLINK0x00004000 |
74 | | APR_FINFO_OWNER0x00030000 | APR_FINFO_PROT0x00700000; |
75 | finfo->protection = apr_unix_mode2perms(info->st_mode); |
76 | finfo->filetype = filetype_from_mode(info->st_mode); |
77 | finfo->user = info->st_uid; |
78 | finfo->group = info->st_gid; |
79 | finfo->size = info->st_size; |
80 | finfo->inode = info->st_ino; |
81 | finfo->device = info->st_dev; |
82 | finfo->nlink = info->st_nlink; |
83 | apr_time_ansi_put(&finfo->atime, info->st_atimest_atim.tv_sec); |
84 | apr_time_ansi_put(&finfo->mtime, info->st_mtimest_mtim.tv_sec); |
85 | apr_time_ansi_put(&finfo->ctime, info->st_ctimest_ctim.tv_sec); |
86 | |
87 | |
88 | |
89 | |
90 | |
91 | |
92 | } |
93 | |
94 | APR_DECLARE(apr_status_t)apr_status_t apr_file_info_get(apr_finfo_t *finfo, |
95 | apr_int32_t wanted, |
96 | apr_file_t *thefile) |
97 | { |
98 | struct_stat info; |
99 | |
100 | if (thefile->buffered) { |
101 | apr_status_t rv = apr_file_flush(thefile); |
102 | if (rv != APR_SUCCESS0) |
103 | return rv; |
104 | } |
105 | |
106 | if (fstat(thefile->filedes, &info) == 0) { |
107 | finfo->pool = thefile->pool; |
108 | finfo->fname = thefile->fname; |
109 | fill_out_finfo(finfo, &info, wanted); |
110 | return (wanted & ~finfo->valid) ? APR_INCOMPLETE((20000 + 50000) + 8) : APR_SUCCESS0; |
111 | } |
112 | else { |
113 | return errno(*__errno_location ()); |
114 | } |
115 | } |
116 | |
117 | APR_DECLARE(apr_status_t)apr_status_t apr_file_perms_set(const char *fname, |
118 | apr_fileperms_t perms) |
119 | { |
120 | mode_t mode = apr_unix_perms2mode(perms); |
121 | |
122 | if (chmod(fname, mode) == -1) |
123 | return errno(*__errno_location ()); |
124 | return APR_SUCCESS0; |
125 | } |
126 | |
127 | APR_DECLARE(apr_status_t)apr_status_t apr_file_attrs_set(const char *fname, |
128 | apr_fileattrs_t attributes, |
129 | apr_fileattrs_t attr_mask, |
130 | apr_pool_t *pool) |
131 | { |
132 | apr_status_t status; |
133 | apr_finfo_t finfo; |
134 | |
135 | |
136 | if (!(attr_mask & (APR_FILE_ATTR_READONLY0x01 |
137 | | APR_FILE_ATTR_EXECUTABLE0x02))) |
138 | return APR_SUCCESS0; |
139 | |
140 | status = apr_stat(&finfo, fname, APR_FINFO_PROT0x00700000, pool); |
141 | if (status) |
142 | return status; |
143 | |
144 | |
145 | if (attr_mask & APR_FILE_ATTR_READONLY0x01) |
146 | { |
147 | if (attributes & APR_FILE_ATTR_READONLY0x01) |
148 | { |
149 | finfo.protection &= ~APR_UWRITE0x0200; |
150 | finfo.protection &= ~APR_GWRITE0x0020; |
151 | finfo.protection &= ~APR_WWRITE0x0002; |
152 | } |
153 | else |
154 | { |
155 | |
156 | finfo.protection |= APR_UWRITE0x0200; |
157 | finfo.protection |= APR_GWRITE0x0020; |
158 | finfo.protection |= APR_WWRITE0x0002; |
159 | } |
160 | } |
161 | |
162 | if (attr_mask & APR_FILE_ATTR_EXECUTABLE0x02) |
163 | { |
164 | if (attributes & APR_FILE_ATTR_EXECUTABLE0x02) |
165 | { |
166 | |
167 | finfo.protection |= APR_UEXECUTE0x0100; |
168 | finfo.protection |= APR_GEXECUTE0x0010; |
169 | finfo.protection |= APR_WEXECUTE0x0001; |
170 | } |
171 | else |
172 | { |
173 | finfo.protection &= ~APR_UEXECUTE0x0100; |
174 | finfo.protection &= ~APR_GEXECUTE0x0010; |
175 | finfo.protection &= ~APR_WEXECUTE0x0001; |
176 | } |
177 | } |
178 | |
179 | return apr_file_perms_set(fname, finfo.protection); |
180 | } |
181 | |
182 | |
183 | APR_DECLARE(apr_status_t)apr_status_t apr_file_mtime_set(const char *fname, |
184 | apr_time_t mtime, |
185 | apr_pool_t *pool) |
186 | { |
187 | apr_status_t status; |
188 | apr_finfo_t finfo; |
189 | |
190 | status = apr_stat(&finfo, fname, APR_FINFO_ATIME0x00000040, pool); |
| |
| 7 | | Returning from 'apr_stat' | |
|
191 | if (status) { |
| |
| |
192 | return status; |
193 | } |
194 | |
195 | #ifdef HAVE_UTIMES1 |
196 | { |
197 | struct timeval tvp[2]; |
198 | |
199 | tvp[0].tv_sec = apr_time_sec(finfo.atime)((finfo.atime) / 1000000L); |
| 10 | | Within the expansion of the macro 'apr_time_sec':
|
a | The left operand of '/' is a garbage value |
|
200 | tvp[0].tv_usec = apr_time_usec(finfo.atime)((finfo.atime) % 1000000L); |
201 | tvp[1].tv_sec = apr_time_sec(mtime)((mtime) / 1000000L); |
202 | tvp[1].tv_usec = apr_time_usec(mtime)((mtime) % 1000000L); |
203 | |
204 | if (utimes(fname, tvp) == -1) { |
205 | return errno(*__errno_location ()); |
206 | } |
207 | } |
208 | #elif defined(HAVE_UTIME1) |
209 | { |
210 | struct utimbuf buf; |
211 | |
212 | buf.actime = (time_t) (finfo.atime / APR_USEC_PER_SEC1000000L); |
213 | buf.modtime = (time_t) (mtime / APR_USEC_PER_SEC1000000L); |
214 | |
215 | if (utime(fname, &buf) == -1) { |
216 | return errno(*__errno_location ()); |
217 | } |
218 | } |
219 | #else |
220 | return APR_ENOTIMPL((20000 + 50000) + 23); |
221 | #endif |
222 | |
223 | return APR_SUCCESS0; |
224 | } |
225 | |
226 | |
227 | APR_DECLARE(apr_status_t)apr_status_t apr_stat(apr_finfo_t *finfo, |
228 | const char *fname, |
229 | apr_int32_t wanted, apr_pool_t *pool) |
230 | { |
231 | struct_stat info; |
232 | int srv; |
233 | |
234 | if (wanted & APR_FINFO_LINK0x00000001) |
| |
235 | srv = lstat(fname, &info); |
236 | else |
237 | srv = stat(fname, &info); |
| |
| |
238 | |
239 | if (srv == 0) { |
| 5 | | Assuming 'srv' is not equal to 0 | |
|
| |
240 | finfo->pool = pool; |
241 | finfo->fname = fname; |
242 | fill_out_finfo(finfo, &info, wanted); |
243 | if (wanted & APR_FINFO_LINK0x00000001) |
244 | wanted &= ~APR_FINFO_LINK0x00000001; |
245 | return (wanted & ~finfo->valid) ? APR_INCOMPLETE((20000 + 50000) + 8) : APR_SUCCESS0; |
246 | } |
247 | else { |
248 | #if !defined(ENOENT2) || !defined(ENOTDIR20) |
249 | #error ENOENT2 || ENOTDIR20 not defined; please see the |
250 | #error comments at this line in the source for a workaround. |
251 | |
252 | |
253 | |
254 | |
255 | |
256 | |
257 | |
258 | |
259 | |
260 | |
261 | |
262 | |
263 | |
264 | |
265 | |
266 | #if !defined(ENOENT2) |
267 | return APR_ENOENT2; |
268 | #else |
269 | |
270 | |
271 | if (errno(*__errno_location ()) != ENOENT2) |
272 | return APR_ENOENT2; |
273 | else |
274 | return errno(*__errno_location ()); |
275 | #endif |
276 | #else /* All was defined well, report the usual: */ |
277 | return errno(*__errno_location ()); |
278 | #endif |
279 | } |
280 | } |
281 | |
282 | |