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
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.
18 #define INCL_DOSERRORS
19 #include "apr_arch_file_io.h"
20 #include "apr_file_io.h"
23 #include "apr_strings.h"
26 static void FS3_to_finfo(apr_finfo_t *finfo, FILESTATUS3 *fstatus)
28 finfo->protection = (fstatus->attrFile & FILE_READONLY) ? 0x555 : 0x777;
30 if (fstatus->attrFile & FILE_DIRECTORY)
31 finfo->filetype = APR_DIR;
33 finfo->filetype = APR_REG;
34 /* XXX: No other possible types from FS3? */
40 finfo->size = fstatus->cbFile;
41 finfo->csize = fstatus->cbFileAlloc;
42 apr_os2_time_to_apr_time(&finfo->atime, fstatus->fdateLastAccess,
43 fstatus->ftimeLastAccess );
44 apr_os2_time_to_apr_time(&finfo->mtime, fstatus->fdateLastWrite,
45 fstatus->ftimeLastWrite );
46 apr_os2_time_to_apr_time(&finfo->ctime, fstatus->fdateCreation,
47 fstatus->ftimeCreation );
48 finfo->valid = APR_FINFO_TYPE | APR_FINFO_PROT | APR_FINFO_SIZE
49 | APR_FINFO_CSIZE | APR_FINFO_MTIME
50 | APR_FINFO_CTIME | APR_FINFO_ATIME | APR_FINFO_LINK;
55 static apr_status_t handle_type(apr_filetype_e *ftype, HFILE file)
57 ULONG filetype, fileattr, rc;
59 rc = DosQueryHType(file, &filetype, &fileattr);
62 switch (filetype & 0xff) {
76 /* Brian, is this correct???
84 return APR_FROM_OS_ERROR(rc);
89 APR_DECLARE(apr_status_t) apr_file_info_get(apr_finfo_t *finfo, apr_int32_t wanted,
95 if (thefile->isopen) {
96 if (thefile->buffered) {
97 apr_status_t rv = apr_file_flush(thefile);
99 if (rv != APR_SUCCESS) {
104 rc = DosQueryFileInfo(thefile->filedes, FIL_STANDARD, &fstatus, sizeof(fstatus));
107 rc = DosQueryPathInfo(thefile->fname, FIL_STANDARD, &fstatus, sizeof(fstatus));
110 FS3_to_finfo(finfo, &fstatus);
111 finfo->fname = thefile->fname;
113 if (finfo->filetype == APR_REG) {
114 if (thefile->isopen) {
115 return handle_type(&finfo->filetype, thefile->filedes);
122 finfo->protection = 0;
123 finfo->filetype = APR_NOFILE;
124 return APR_FROM_OS_ERROR(rc);
127 APR_DECLARE(apr_status_t) apr_file_perms_set(const char *fname, apr_fileperms_t perms)
133 APR_DECLARE(apr_status_t) apr_stat(apr_finfo_t *finfo, const char *fname,
134 apr_int32_t wanted, apr_pool_t *cont)
139 finfo->protection = 0;
140 finfo->filetype = APR_NOFILE;
142 rc = DosQueryPathInfo(fname, FIL_STANDARD, &fstatus, sizeof(fstatus));
145 FS3_to_finfo(finfo, &fstatus);
146 finfo->fname = fname;
148 if (wanted & APR_FINFO_NAME) {
150 HDIR hDir = HDIR_SYSTEM;
152 rc = DosFindFirst(fname, &hDir,
153 FILE_DIRECTORY|FILE_HIDDEN|FILE_SYSTEM|FILE_ARCHIVED,
154 &ffb, sizeof(ffb), &count, FIL_STANDARD);
155 if (rc == 0 && count == 1) {
156 finfo->name = apr_pstrdup(cont, ffb.achName);
157 finfo->valid |= APR_FINFO_NAME;
160 } else if (rc == ERROR_INVALID_ACCESS) {
161 memset(finfo, 0, sizeof(apr_finfo_t));
162 finfo->valid = APR_FINFO_TYPE | APR_FINFO_PROT;
163 finfo->protection = 0666;
164 finfo->filetype = APR_CHR;
166 if (wanted & APR_FINFO_NAME) {
167 finfo->name = apr_pstrdup(cont, fname);
168 finfo->valid |= APR_FINFO_NAME;
171 return APR_FROM_OS_ERROR(rc);
174 return (wanted & ~finfo->valid) ? APR_INCOMPLETE : APR_SUCCESS;
179 APR_DECLARE(apr_status_t) apr_lstat(apr_finfo_t *finfo, const char *fname,
180 apr_int32_t wanted, apr_pool_t *cont)
182 return apr_stat(finfo, fname, wanted, cont);
187 APR_DECLARE(apr_status_t) apr_file_attrs_set(const char *fname,
188 apr_fileattrs_t attributes,
189 apr_fileattrs_t attr_mask,
195 /* Don't do anything if we can't handle the requested attributes */
196 if (!(attr_mask & (APR_FILE_ATTR_READONLY
197 | APR_FILE_ATTR_HIDDEN)))
200 rc = DosQueryPathInfo(fname, FIL_STANDARD, &fs3, sizeof(fs3));
202 ULONG old_attr = fs3.attrFile;
204 if (attr_mask & APR_FILE_ATTR_READONLY)
206 if (attributes & APR_FILE_ATTR_READONLY) {
207 fs3.attrFile |= FILE_READONLY;
209 fs3.attrFile &= ~FILE_READONLY;
213 if (attr_mask & APR_FILE_ATTR_HIDDEN)
215 if (attributes & APR_FILE_ATTR_HIDDEN) {
216 fs3.attrFile |= FILE_HIDDEN;
218 fs3.attrFile &= ~FILE_HIDDEN;
222 if (fs3.attrFile != old_attr) {
223 rc = DosSetPathInfo(fname, FIL_STANDARD, &fs3, sizeof(fs3), 0);
227 return APR_FROM_OS_ERROR(rc);
231 /* ### Somebody please write this! */
232 APR_DECLARE(apr_status_t) apr_file_mtime_set(const char *fname,