1
/* Copyright 2000-2005 The Apache Software Foundation or its licensors, as
4
* Licensed under the Apache License, Version 2.0 (the "License");
5
* you may not use this file except in compliance with the License.
6
* You may obtain a copy of the License at
8
* http://www.apache.org/licenses/LICENSE-2.0
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.
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"
27
static apr_filetype_e filetype_from_mode(mode_t mode)
31
switch (mode & S_IFMT) {
33
type = APR_REG; break;
35
type = APR_DIR; break;
37
type = APR_LNK; break;
39
type = APR_CHR; break;
41
type = APR_BLK; break;
44
type = APR_PIPE; break;
46
#if !defined(BEOS) && defined(S_IFSOCK)
48
type = APR_SOCK; break;
52
/* Work around missing S_IFxxx values above
55
#if !defined(S_IFFIFO) && defined(S_ISFIFO)
60
#if !defined(BEOS) && !defined(S_IFSOCK) && defined(S_ISSOCK)
70
static void fill_out_finfo(apr_finfo_t *finfo, struct_stat *info,
73
finfo->valid = APR_FINFO_MIN | APR_FINFO_IDENT | APR_FINFO_NLINK
74
| APR_FINFO_OWNER | APR_FINFO_PROT;
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_atime);
84
apr_time_ansi_put(&finfo->mtime, info->st_mtime);
85
apr_time_ansi_put(&finfo->ctime, info->st_ctime);
86
/* ### needs to be revisited
87
* if (wanted & APR_FINFO_CSIZE) {
88
* finfo->csize = info->st_blocks * 512;
89
* finfo->valid |= APR_FINFO_CSIZE;
94
APR_DECLARE(apr_status_t) apr_file_info_get(apr_finfo_t *finfo,
100
if (thefile->buffered) {
101
apr_status_t rv = apr_file_flush(thefile);
102
if (rv != APR_SUCCESS)
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 : APR_SUCCESS;
117
APR_DECLARE(apr_status_t) apr_file_perms_set(const char *fname,
118
apr_fileperms_t perms)
120
mode_t mode = apr_unix_perms2mode(perms);
122
if (chmod(fname, mode) == -1)
127
APR_DECLARE(apr_status_t) apr_file_attrs_set(const char *fname,
128
apr_fileattrs_t attributes,
129
apr_fileattrs_t attr_mask,
135
/* Don't do anything if we can't handle the requested attributes */
136
if (!(attr_mask & (APR_FILE_ATTR_READONLY
137
| APR_FILE_ATTR_EXECUTABLE)))
140
status = apr_stat(&finfo, fname, APR_FINFO_PROT, pool);
144
/* ### TODO: should added bits be umask'd? */
145
if (attr_mask & APR_FILE_ATTR_READONLY)
147
if (attributes & APR_FILE_ATTR_READONLY)
149
finfo.protection &= ~APR_UWRITE;
150
finfo.protection &= ~APR_GWRITE;
151
finfo.protection &= ~APR_WWRITE;
155
/* ### umask this! */
156
finfo.protection |= APR_UWRITE;
157
finfo.protection |= APR_GWRITE;
158
finfo.protection |= APR_WWRITE;
162
if (attr_mask & APR_FILE_ATTR_EXECUTABLE)
164
if (attributes & APR_FILE_ATTR_EXECUTABLE)
166
/* ### umask this! */
167
finfo.protection |= APR_UEXECUTE;
168
finfo.protection |= APR_GEXECUTE;
169
finfo.protection |= APR_WEXECUTE;
173
finfo.protection &= ~APR_UEXECUTE;
174
finfo.protection &= ~APR_GEXECUTE;
175
finfo.protection &= ~APR_WEXECUTE;
179
return apr_file_perms_set(fname, finfo.protection);
183
APR_DECLARE(apr_status_t) apr_file_mtime_set(const char *fname,
190
status = apr_stat(&finfo, fname, APR_FINFO_ATIME, pool);
197
struct timeval tvp[2];
199
tvp[0].tv_sec = apr_time_sec(finfo.atime);
200
tvp[0].tv_usec = apr_time_usec(finfo.atime);
201
tvp[1].tv_sec = apr_time_sec(mtime);
202
tvp[1].tv_usec = apr_time_usec(mtime);
204
if (utimes(fname, tvp) == -1) {
208
#elif defined(HAVE_UTIME)
212
buf.actime = (time_t) (finfo.atime / APR_USEC_PER_SEC);
213
buf.modtime = (time_t) (mtime / APR_USEC_PER_SEC);
215
if (utime(fname, &buf) == -1) {
227
APR_DECLARE(apr_status_t) apr_stat(apr_finfo_t *finfo,
229
apr_int32_t wanted, apr_pool_t *pool)
234
if (wanted & APR_FINFO_LINK)
235
srv = lstat(fname, &info);
237
srv = stat(fname, &info);
241
finfo->fname = fname;
242
fill_out_finfo(finfo, &info, wanted);
243
if (wanted & APR_FINFO_LINK)
244
wanted &= ~APR_FINFO_LINK;
245
return (wanted & ~finfo->valid) ? APR_INCOMPLETE : APR_SUCCESS;
248
#if !defined(ENOENT) || !defined(ENOTDIR)
249
#error ENOENT || ENOTDIR not defined; please see the
250
#error comments at this line in the source for a workaround.
252
* If ENOENT || ENOTDIR is not defined in one of the your OS's
253
* include files, APR cannot report a good reason why the stat()
254
* of the file failed; there are cases where it can fail even though
255
* the file exists. This opens holes in Apache, for example, because
256
* it becomes possible for someone to get a directory listing of a
257
* directory even though there is an index (eg. index.html) file in
258
* it. If you do not have a problem with this, delete the above
259
* #error lines and start the compile again. If you need to do this,
260
* please submit a bug report to http://www.apache.org/bug_report.html
261
* letting us know that you needed to do this. Please be sure to
262
* include the operating system you are using.
264
/* WARNING: All errors will be handled as not found
269
/* WARNING: All errors but not found will be handled as not directory
276
#else /* All was defined well, report the usual: */