Apache HTTPD
filestat.c
Go to the documentation of this file.
1/* Licensed to the Apache Software Foundation (ASF) under one or more
2 * contributor license agreements. See the NOTICE file distributed with
3 * this work for additional information regarding copyright ownership.
4 * The ASF licenses this file to You under the Apache License, Version 2.0
5 * (the "License"); you may not use this file except in compliance with
6 * the License. You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
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_UTIME
24#include <utime.h>
25#endif
26
28{
30
31 switch (mode & S_IFMT) {
32 case S_IFREG:
33 type = APR_REG; break;
34 case S_IFDIR:
35 type = APR_DIR; break;
36 case S_IFLNK:
37 type = APR_LNK; break;
38 case S_IFCHR:
39 type = APR_CHR; break;
40 case S_IFBLK:
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_IFSOCK)
47 case S_IFSOCK:
48 type = APR_SOCK; break;
49#endif
50
51 default:
52 /* Work around missing S_IFxxx values above
53 * for Linux et al.
54 */
55#if !defined(S_IFFIFO) && defined(S_ISFIFO)
56 if (S_ISFIFO(mode)) {
57 type = APR_PIPE;
58 } else
59#endif
60#if !defined(BEOS) && !defined(S_IFSOCK) && defined(S_ISSOCK)
61 if (S_ISSOCK(mode)) {
62 type = APR_SOCK;
63 } else
64#endif
66 }
67 return type;
68}
69
72{
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->device = info->st_dev;
81 finfo->nlink = info->st_nlink;
82
83 /* Check for overflow if storing a 64-bit st_ino in a 32-bit
84 * apr_ino_t for LFS builds: */
85 if (sizeof(apr_ino_t) >= sizeof(info->st_ino)
86 || (apr_ino_t)info->st_ino == info->st_ino) {
87 finfo->inode = info->st_ino;
88 } else {
89 finfo->valid &= ~APR_FINFO_INODE;
90 }
91
92 apr_time_ansi_put(&finfo->atime, info->st_atime);
93#ifdef HAVE_STRUCT_STAT_ST_ATIM_TV_NSEC
94 finfo->atime += info->st_atim.tv_nsec / APR_TIME_C(1000);
95#elif defined(HAVE_STRUCT_STAT_ST_ATIMENSEC)
96 finfo->atime += info->st_atimensec / APR_TIME_C(1000);
97#elif defined(HAVE_STRUCT_STAT_ST_ATIME_N)
98 finfo->atime += info->st_atime_n / APR_TIME_C(1000);
99#endif
100
101 apr_time_ansi_put(&finfo->mtime, info->st_mtime);
102#ifdef HAVE_STRUCT_STAT_ST_MTIM_TV_NSEC
103 finfo->mtime += info->st_mtim.tv_nsec / APR_TIME_C(1000);
104#elif defined(HAVE_STRUCT_STAT_ST_MTIMENSEC)
105 finfo->mtime += info->st_mtimensec / APR_TIME_C(1000);
106#elif defined(HAVE_STRUCT_STAT_ST_MTIME_N)
107 finfo->mtime += info->st_mtime_n / APR_TIME_C(1000);
108#endif
109
110 apr_time_ansi_put(&finfo->ctime, info->st_ctime);
111#ifdef HAVE_STRUCT_STAT_ST_CTIM_TV_NSEC
112 finfo->ctime += info->st_ctim.tv_nsec / APR_TIME_C(1000);
113#elif defined(HAVE_STRUCT_STAT_ST_CTIMENSEC)
114 finfo->ctime += info->st_ctimensec / APR_TIME_C(1000);
115#elif defined(HAVE_STRUCT_STAT_ST_CTIME_N)
116 finfo->ctime += info->st_ctime_n / APR_TIME_C(1000);
117#endif
118
119#ifdef HAVE_STRUCT_STAT_ST_BLOCKS
120#ifdef DEV_BSIZE
121 finfo->csize = (apr_off_t)info->st_blocks * (apr_off_t)DEV_BSIZE;
122#else
123 finfo->csize = (apr_off_t)info->st_blocks * (apr_off_t)512;
124#endif
125 finfo->valid |= APR_FINFO_CSIZE;
126#endif
127}
128
131{
133
134 if (thefile->buffered) {
136 if (rv != APR_SUCCESS)
137 return rv;
138 }
139
140 if (fstat(thefile->filedes, &info) == 0) {
141 finfo->pool = thefile->pool;
142 finfo->fname = thefile->fname;
143 fill_out_finfo(finfo, &info, wanted);
144 return (wanted & ~finfo->valid) ? APR_INCOMPLETE : APR_SUCCESS;
145 }
146 else {
147 return errno;
148 }
149}
150
154{
156
157 if (thefile->buffered) {
159 if (rv != APR_SUCCESS)
160 return rv;
161 }
162
163 if (fstat(thefile->filedes, &info) == 0) {
164 finfo->pool = thefile->pool;
165 finfo->fname = thefile->fname;
166 fill_out_finfo(finfo, &info, wanted);
167 return (wanted & ~finfo->valid) ? APR_INCOMPLETE : APR_SUCCESS;
168 }
169 else {
170 return errno;
171 }
172}
173
176{
178
179 if (chmod(fname, mode) == -1)
180 return errno;
181 return APR_SUCCESS;
182}
183
188{
190 apr_finfo_t finfo;
191
192 /* Don't do anything if we can't handle the requested attributes */
195 return APR_SUCCESS;
196
198 if (status)
199 return status;
200
201 /* ### TODO: should added bits be umask'd? */
203 {
205 {
206 finfo.protection &= ~APR_UWRITE;
207 finfo.protection &= ~APR_GWRITE;
208 finfo.protection &= ~APR_WWRITE;
209 }
210 else
211 {
212 /* ### umask this! */
213 finfo.protection |= APR_UWRITE;
214 finfo.protection |= APR_GWRITE;
215 finfo.protection |= APR_WWRITE;
216 }
217 }
218
220 {
222 {
223 /* ### umask this! */
224 finfo.protection |= APR_UEXECUTE;
225 finfo.protection |= APR_GEXECUTE;
226 finfo.protection |= APR_WEXECUTE;
227 }
228 else
229 {
230 finfo.protection &= ~APR_UEXECUTE;
231 finfo.protection &= ~APR_GEXECUTE;
232 finfo.protection &= ~APR_WEXECUTE;
233 }
234 }
235
236 return apr_file_perms_set(fname, finfo.protection);
237}
238
239
243{
245 apr_finfo_t finfo;
246
248 if (status) {
249 return status;
250 }
251
252#ifdef HAVE_UTIMES
253 {
254 struct timeval tvp[2];
255
256 tvp[0].tv_sec = apr_time_sec(finfo.atime);
257 tvp[0].tv_usec = apr_time_usec(finfo.atime);
258 tvp[1].tv_sec = apr_time_sec(mtime);
259 tvp[1].tv_usec = apr_time_usec(mtime);
260
261 if (utimes(fname, tvp) == -1) {
262 return errno;
263 }
264 }
265#elif defined(HAVE_UTIME)
266 {
267 struct utimbuf buf;
268
269 buf.actime = (time_t) (finfo.atime / APR_USEC_PER_SEC);
270 buf.modtime = (time_t) (mtime / APR_USEC_PER_SEC);
271
272 if (utime(fname, &buf) == -1) {
273 return errno;
274 }
275 }
276#else
277 return APR_ENOTIMPL;
278#endif
279
280 return APR_SUCCESS;
281}
282
283
285 const char *fname,
287{
289 int srv;
290
292 srv = lstat(fname, &info);
293 else
294 srv = stat(fname, &info);
295
296 if (srv == 0) {
297 finfo->pool = pool;
298 finfo->fname = fname;
299 fill_out_finfo(finfo, &info, wanted);
302 return (wanted & ~finfo->valid) ? APR_INCOMPLETE : APR_SUCCESS;
303 }
304 else {
305#if !defined(ENOENT) || !defined(ENOTDIR)
306#error ENOENT || ENOTDIR not defined; please see the
307#error comments at this line in the source for a workaround.
308 /*
309 * If ENOENT || ENOTDIR is not defined in one of the your OS's
310 * include files, APR cannot report a good reason why the stat()
311 * of the file failed; there are cases where it can fail even though
312 * the file exists. This opens holes in Apache, for example, because
313 * it becomes possible for someone to get a directory listing of a
314 * directory even though there is an index (eg. index.html) file in
315 * it. If you do not have a problem with this, delete the above
316 * #error lines and start the compile again. If you need to do this,
317 * please submit a bug report to http://www.apache.org/bug_report.html
318 * letting us know that you needed to do this. Please be sure to
319 * include the operating system you are using.
320 */
321 /* WARNING: All errors will be handled as not found
322 */
323#if !defined(ENOENT)
324 return APR_ENOENT;
325#else
326 /* WARNING: All errors but not found will be handled as not directory
327 */
328 if (errno != ENOENT)
329 return APR_ENOENT;
330 else
331 return errno;
332#endif
333#else /* All was defined well, report the usual: */
334 return errno;
335#endif
336 }
337}
338
339
mode_t
Definition aplibtool.c:31
APR Error Codes.
APR File I/O Handling.
APR Miscellaneous library routines.
APR Strings library.
const unsigned char * buf
Definition util_md5.h:50
#define APR_INCOMPLETE
Definition apr_errno.h:452
#define APR_ENOTIMPL
Definition apr_errno.h:476
#define APR_ENOENT
Definition apr_errno.h:662
apr_dbd_transaction_t int mode
Definition apr_dbd.h:261
const void apr_status_t(*) apr_status_t(* APR_DECLARE)(void) apr_pool_pre_cleanup_register(apr_pool_t *p
Definition apr_pools.h:646
apr_size_t size
const char int apr_pool_t * pool
Definition apr_cstr.h:84
#define APR_SUCCESS
Definition apr_errno.h:225
int apr_status_t
Definition apr_errno.h:44
#define APR_FILE_ATTR_READONLY
#define APR_FILE_ATTR_EXECUTABLE
apr_int32_t apr_fileperms_t
apr_filetype_e
@ APR_BLK
@ APR_PIPE
@ APR_LNK
@ APR_UNKFILE
@ APR_REG
@ APR_CHR
@ APR_SOCK
@ APR_DIR
apr_file_t * thefile
apr_uint32_t apr_fileattrs_t
const char apr_fileperms_t perms
apr_fileattrs_t attributes
int type
apr_time_t mtime
apr_fileattrs_t apr_fileattrs_t attr_mask
#define APR_UEXECUTE
#define APR_UWRITE
#define APR_GWRITE
#define APR_GEXECUTE
#define APR_WWRITE
#define APR_WEXECUTE
#define APR_FINFO_ATIME
#define APR_FINFO_OWNER
#define APR_FINFO_MIN
#define APR_FINFO_IDENT
const char apr_int32_t wanted
const char * fname
#define APR_FINFO_LINK
#define APR_FINFO_NLINK
#define APR_FINFO_PROT
#define APR_FINFO_CSIZE
int int status
#define APR_TIME_C(val)
Definition apr_time.h:49
#define APR_USEC_PER_SEC
Definition apr_time.h:60
apr_int64_t apr_time_t
Definition apr_time.h:45
#define apr_time_sec(time)
Definition apr_time.h:63
#define apr_time_usec(time)
Definition apr_time.h:66
struct stat struct_stat
static void fill_out_finfo(apr_finfo_t *finfo, struct stat *info, apr_int32_t wanted)
Definition filestat.c:56
static apr_filetype_e filetype_from_mode(mode_t mode)
Definition filestat.c:33
apr_status_t apr_file_info_get_locked(apr_finfo_t *finfo, apr_int32_t wanted, apr_file_t *thefile)
Definition filestat.c:85
#define S_IFREG
Definition readfilemap.c:66
#define S_IFMT
Definition readfilemap.c:69
apr_pool_t * pool
apr_gid_t group
apr_filetype_e filetype
apr_dev_t device
apr_off_t size
apr_pool_t * pool
apr_ino_t inode
apr_fileperms_t protection
apr_int32_t nlink
apr_uid_t user
const char * fname
apr_time_t atime
apr_off_t csize
apr_time_t ctime
apr_time_t mtime
apr_int32_t valid
mode_t apr_unix_perms2mode(apr_fileperms_t perms)
Definition fileacc.c:35
apr_fileperms_t apr_unix_mode2perms(mode_t mode)
Definition fileacc.c:71
apr_status_t apr_file_flush_locked(apr_file_t *thefile)
Definition readwrite.c:313
INT info