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.h"
18#include <aclapi.h>
19#include "apr_private.h"
20#include "apr_arch_file_io.h"
21#include "apr_file_io.h"
22#include "apr_general.h"
23#include "apr_strings.h"
24#include "apr_errno.h"
25#include "apr_time.h"
26#include <sys/stat.h>
27#include "apr_arch_atime.h"
28#include "apr_arch_misc.h"
29
30/* We have to assure that the file name contains no '*'s, or other
31 * wildcards when using FindFirstFile to recover the true file name.
32 */
33static apr_status_t test_safe_name(const char *name)
34{
35 /* Only accept ':' in the second position of the filename,
36 * as the drive letter delimiter:
37 */
38 if (apr_isalpha(*name) && (name[1] == ':')) {
39 name += 2;
40 }
41 while (*name) {
42 if (!IS_FNCHAR(*name) && (*name != '\\') && (*name != '/')) {
43 if (*name == '?' || *name == '*')
44 return APR_EPATHWILD;
45 else
46 return APR_EBADPATH;
47 }
48 ++name;
49 }
50 return APR_SUCCESS;
51}
52
53static apr_status_t free_localheap(void *heap) {
54 LocalFree(heap);
55 return APR_SUCCESS;
56}
57
59
60static void free_world(void)
61{
62 if (worldid) {
64 worldid = NULL;
65 }
66}
67
68/* Left bit shifts from World scope to given scope */
74
76{
77 /* These choices are based on the single filesystem bit that controls
78 * the given behavior. They are -not- recommended for any set protection
79 * function, such a function should -set- use GENERIC_READ/WRITE/EXECUTE
80 */
82 if (acc & FILE_EXECUTE)
84 if (acc & FILE_WRITE_DATA)
86 if (acc & FILE_READ_DATA)
87 prot |= APR_WREAD;
88 return (prot << scope);
89}
90
92{
95 /*
96 * This function is only invoked for WinNT,
97 * there is no reason for os_level testing here.
98 */
99 if ((wanted & APR_FINFO_WPROT) && !worldid) {
102 0, 0, 0, 0, 0, 0, 0, &worldid))
104 else
105 worldid = NULL;
106 }
107 if ((wanted & APR_FINFO_UPROT) && (finfo->valid & APR_FINFO_USER)) {
108 ident.TrusteeType = TRUSTEE_IS_USER;
109 ident.ptstrName = finfo->user;
110 /* GetEffectiveRightsFromAcl isn't supported under Win9x,
111 * which shouldn't come as a surprize. Since we are passing
112 * TRUSTEE_IS_SID, always skip the A->W layer.
113 */
116 finfo->valid |= APR_FINFO_UPROT;
117 }
118 }
119 /* Windows NT: did not return group rights.
120 * Windows 2000 returns group rights information.
121 * Since WinNT kernels don't follow the unix model of
122 * group associations, this all all pretty mute.
123 */
124 if ((wanted & APR_FINFO_GPROT) && (finfo->valid & APR_FINFO_GROUP)) {
125 ident.TrusteeType = TRUSTEE_IS_GROUP;
126 ident.ptstrName = finfo->group;
129 finfo->valid |= APR_FINFO_GPROT;
130 }
131 }
132 if ((wanted & APR_FINFO_WPROT) && (worldid)) {
134 ident.ptstrName = worldid;
137 finfo->valid |= APR_FINFO_WPROT;
138 }
139 }
140}
141
142static apr_status_t resolve_ident(apr_finfo_t *finfo, const char *fname,
144{
146 apr_status_t rv;
147 /*
148 * NT5 (W2K) only supports symlinks in the same manner as mount points.
149 * This code should eventually take that into account, for now treat
150 * every reparse point as a symlink...
151 *
152 * We must open the file with READ_CONTROL if we plan to retrieve the
153 * user, group or permissions.
154 */
155
159 ? APR_READCONTROL : 0),
161 rv = apr_file_info_get(finfo, wanted, thefile);
162 finfo->filehand = NULL;
164 }
165 else if (APR_STATUS_IS_EACCES(rv) && (wanted & (APR_FINFO_PROT
166 | APR_FINFO_OWNER))) {
167 /* We have a backup plan. Perhaps we couldn't grab READ_CONTROL?
168 * proceed without asking for that permission...
169 */
171 | ((wanted & APR_FINFO_LINK) ? APR_OPENLINK : 0),
175 thefile);
176 finfo->filehand = NULL;
178 }
179 }
180
181 if (rv != APR_SUCCESS && rv != APR_INCOMPLETE)
182 return (rv);
183
184 /* We picked up this case above and had opened the link's properties */
186 finfo->valid |= APR_FINFO_LINK;
187
188 return rv;
189}
190
193{
194 /* Read, write execute for owner. In the Win9x environment, any
195 * readable file is executable (well, not entirely 100% true, but
196 * still looking for some cheap logic that would help us here.)
197 * The same holds on NT if a file doesn't have a DACL (e.g., on FAT)
198 */
199 if (finfo->protection & APR_FREADONLY) {
201 }
202 else {
204 }
205 finfo->protection |= (finfo->protection << prot_scope_group)
206 | (finfo->protection << prot_scope_user);
207
209
210 return ((wanted & ~finfo->valid) ? APR_INCOMPLETE : APR_SUCCESS);
211}
212
214 int finddata, const char *fname)
215{
216 int tag = 0;
217
218 if (!(wininfo->dwFileAttributes & FILE_ATTRIBUTE_REPARSE_POINT))
219 {
220 return 0;
221 }
222
223 if (finddata)
224 {
225 // no matter A or W as we don't need file name
226 tag = ((WIN32_FIND_DATAA*)wininfo)->dwReserved0;
227 }
228 else
229 {
231 return 0;
232 }
233
234#if APR_HAS_UNICODE_FS
236 {
240
242 return 0;
243 }
244
247 return 0;
248 }
249
251
252 tag = fd.dwReserved0;
253 }
254#endif
255#if APR_HAS_ANSI_FS || 1
257 {
260
263 return 0;
264 }
265
267
268 tag = fd.dwReserved0;
269 }
270#endif
271 }
272
273 // Test "Name surrogate bit" to detect any kind of symbolic link
274 // See https://docs.microsoft.com/en-us/windows/desktop/fileio/reparse-point-tags
275 return tag & 0x20000000;
276}
277
280{
281 PSID user = NULL, grp = NULL;
282 PACL dacl = NULL;
283 apr_status_t rv;
284
286 return guess_protection_bits(finfo, wanted);
287
289 {
290 /* On NT this request is incredibly expensive, but accurate.
291 * Since the WinNT-only functions below are protected by the
292 * (apr_os_level < APR_WIN_NT) case above, we need no extra
293 * tests, but remember GetNamedSecurityInfo & GetSecurityInfo
294 * are not supported on 9x.
295 */
304 if (whatfile == MORE_OF_WFSPEC) {
306 int fix = 0;
307 if (wcsncmp(wfile, L"\\\\?\\", 4) == 0) {
308 fix = 4;
309 if (wcsncmp(wfile + fix, L"UNC\\", 4) == 0)
310 wfile[6] = L'\\', fix = 6;
311 }
314 ((wanted & (APR_FINFO_USER | APR_FINFO_UPROT)) ? &user : NULL),
316 ((wanted & APR_FINFO_PROT) ? &dacl : NULL),
317 NULL, &pdesc);
318 if (fix == 6)
319 wfile[6] = L'C';
320 }
321 else if (whatfile == MORE_OF_FSPEC)
322 rv = GetNamedSecurityInfoA((char*)ufile,
324 ((wanted & (APR_FINFO_USER | APR_FINFO_UPROT)) ? &user : NULL),
326 ((wanted & APR_FINFO_PROT) ? &dacl : NULL),
327 NULL, &pdesc);
328 else if (whatfile == MORE_OF_HANDLE)
331 ((wanted & (APR_FINFO_USER | APR_FINFO_UPROT)) ? &user : NULL),
333 ((wanted & APR_FINFO_PROT) ? &dacl : NULL),
334 NULL, &pdesc);
335 else
336 return APR_INCOMPLETE; /* should not occur */
337 if (rv == ERROR_SUCCESS)
340 else
341 user = grp = dacl = NULL;
342
343 if (user) {
344 finfo->user = user;
345 finfo->valid |= APR_FINFO_USER;
346 }
347
348 if (grp) {
349 finfo->group = grp;
350 finfo->valid |= APR_FINFO_GROUP;
351 }
352
353 if (dacl) {
354 /* Retrieved the discresionary access list */
355 resolve_prot(finfo, wanted, dacl);
356 }
357 else if (wanted & APR_FINFO_PROT)
359 }
360
362 && (finfo->filetype == APR_REG))
363 {
365 if (whatfile == MORE_OF_HANDLE) {
366 /* Not available for development and implementation under
367 * a reasonable license; if you review the licensing
368 * terms and conditions of;
369 * http://go.microsoft.com/fwlink/?linkid=84083
370 * you probably understand why APR chooses not to implement.
371 */
372 IOSB sb;
373 FSI fi;
375 &fi, sizeof(fi), 5) == 0)
376 && (sb.Status == 0)) {
377 finfo->csize = fi.AllocationSize;
378 finfo->valid |= APR_FINFO_CSIZE;
379 }
380 }
381 else {
385 else if (whatfile == MORE_OF_FSPEC)
387 else
388 return APR_EGENERAL; /* should not occur */
389
391#if APR_HAS_LARGE_FILES
392 finfo->csize = (apr_off_t)sizelo
393 | ((apr_off_t)sizehi << 32);
394#else
395 finfo->csize = (apr_off_t)sizelo;
396 if (finfo->csize < 0 || sizehi)
397 finfo->csize = 0x7fffffff;
398#endif
399 finfo->valid |= APR_FINFO_CSIZE;
400 }
401 }
402 }
403 return ((wanted & ~finfo->valid) ? APR_INCOMPLETE : APR_SUCCESS);
404}
405
406
407/* This generic fillin depends upon byhandle to be passed as 0 when
408 * a WIN32_FILE_ATTRIBUTE_DATA or either WIN32_FIND_DATA [A or W] is
409 * passed for wininfo. When the BY_HANDLE_FILE_INFORMATION structure
410 * is passed for wininfo, byhandle is passed as 1 to offset the one
411 * dword discrepancy in offset of the High/Low size structure members.
412 *
413 * The generic fillin returns 1 if the caller should further inquire
414 * if this is a CHR filetype. If it's reasonably certain it can't be,
415 * then the function returns 0.
416 */
419 int byhandle,
420 int finddata,
421 const char *fname,
423{
424 DWORD *sizes = &wininfo->nFileSizeHigh + byhandle;
425 int warn = 0;
426
427 memset(finfo, '\0', sizeof(*finfo));
428
429 FileTimeToAprTime(&finfo->atime, &wininfo->ftLastAccessTime);
430 FileTimeToAprTime(&finfo->ctime, &wininfo->ftCreationTime);
431 FileTimeToAprTime(&finfo->mtime, &wininfo->ftLastWriteTime);
432
433#if APR_HAS_LARGE_FILES
434 finfo->size = (apr_off_t)sizes[1]
435 | ((apr_off_t)sizes[0] << 32);
436#else
437 finfo->size = (apr_off_t)sizes[1];
438 if (finfo->size < 0 || sizes[0])
439 finfo->size = 0x7fffffff;
440#endif
441
442 if (wanted & APR_FINFO_LINK &&
444 finfo->filetype = APR_LNK;
445 }
446 else if (wininfo->dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) {
447 finfo->filetype = APR_DIR;
448 }
449 else if (wininfo->dwFileAttributes & FILE_ATTRIBUTE_DEVICE) {
450 /* Warning: This test only succeeds on Win9x, on NT these files
451 * (con, aux, nul, lpt#, com# etc) escape early detection!
452 */
453 finfo->filetype = APR_CHR;
454 }
455 else {
456 /* Warning: Short of opening the handle to the file, the 'FileType'
457 * appears to be unknowable (in any trustworthy or consistent sense)
458 * on WinNT/2K as far as PIPE, CHR, etc are concerned.
459 */
460 if (!wininfo->ftLastWriteTime.dwLowDateTime
461 && !wininfo->ftLastWriteTime.dwHighDateTime
462 && !finfo->size)
463 warn = 1;
464 finfo->filetype = APR_REG;
465 }
466
467 /* The following flags are [for this moment] private to Win32.
468 * That's the only excuse for not toggling valid bits to reflect them.
469 */
470 if (wininfo->dwFileAttributes & FILE_ATTRIBUTE_READONLY)
471 finfo->protection = APR_FREADONLY;
472
474 | APR_FINFO_SIZE | APR_FINFO_TYPE; /* == APR_FINFO_MIN */
475
476 /* Only byhandle optionally tests link targets, so tell that caller
477 * what it wants to hear, otherwise the byattributes is never
478 * reporting anything but the link.
479 */
480 if (!byhandle || (wanted & APR_FINFO_LINK))
481 finfo->valid |= APR_FINFO_LINK;
482 return warn;
483}
484
485
488{
490
491 if (thefile->buffered) {
492 /* XXX: flush here is not mutex protected */
494 if (rv != APR_SUCCESS)
495 return rv;
496 }
497
498 /* GetFileInformationByHandle() is implemented via two syscalls:
499 * QueryInformationVolume and QueryAllInformationFile. Use cheaper
500 * GetFileSizeEx() API if we only need to get the file size. */
501 if (wanted == APR_FINFO_SIZE) {
503
505 return apr_get_os_error();
506 }
507
508 finfo->pool = thefile->pool;
509 finfo->fname = thefile->fname;
510 finfo->size = size.QuadPart;
511 finfo->valid = APR_FINFO_SIZE;
512
513 return APR_SUCCESS;
514 }
515
517 return apr_get_os_error();
518 }
519
521
522 if (finfo->filetype == APR_REG)
523 {
524 /* Go the extra mile to be -certain- that we have a real, regular
525 * file, since the attribute bits aren't a certain thing. Even
526 * though fillin should have hinted if we *must* do this, we
527 * don't need to take chances while the handle is already open.
528 */
531 if (FileType == FILE_TYPE_CHAR) {
532 finfo->filetype = APR_CHR;
533 }
534 else if (FileType == FILE_TYPE_PIPE) {
535 finfo->filetype = APR_PIPE;
536 }
537 /* Otherwise leave the original conclusion alone
538 */
539 }
540 }
541
542 finfo->pool = thefile->pool;
543
544 /* ### The finfo lifetime may exceed the lifetime of thefile->pool
545 * but finfo's aren't managed in pools, so where on earth would
546 * we pstrdup the fname into???
547 */
548 finfo->fname = thefile->fname;
549
550 /* Extra goodies known only by GetFileInformationByHandle() */
551 finfo->inode = (apr_ino_t)FileInfo.nFileIndexLow
552 | ((apr_ino_t)FileInfo.nFileIndexHigh << 32);
553 finfo->device = FileInfo.dwVolumeSerialNumber;
554 finfo->nlink = FileInfo.nNumberOfLinks;
555
557
558 /* If we still want something more (besides the name) go get it!
559 */
560 if ((wanted &= ~finfo->valid) & ~APR_FINFO_NAME) {
562 }
563
564 return APR_SUCCESS;
565}
566
569{
570 return APR_ENOTIMPL;
571}
572
575{
576 /* XXX: is constant - needs testing - which requires a lighter-weight root test fn */
577 int isroot = 0;
579 apr_status_t rv;
580#if APR_HAS_UNICODE_FS
582
583#endif
584 char *filename = NULL;
585 /* These all share a common subset of this structure */
586 union {
590 } FileInfo;
591 int finddata = 0;
592
593 /* Catch fname length == MAX_PATH since GetFileAttributesEx fails
594 * with PATH_NOT_FOUND. We would rather indicate length error than
595 * 'not found'
596 */
597 if (strlen(fname) >= APR_PATH_MAX) {
598 return APR_ENAMETOOLONG;
599 }
600
601#if APR_HAS_UNICODE_FS
603 {
605 || (~wanted & APR_FINFO_LINK)) {
606 /* FindFirstFile and GetFileAttributesEx can't figure the inode,
607 * device or number of links, so we need to resolve with an open
608 * file handle. If the user has asked for these fields, fall over
609 * to the get file info by handle method. If we fail, or the user
610 * also asks for the file name, continue by our usual means.
611 *
612 * We also must use this method for a 'true' stat, that resolves
613 * a symlink (NTFS Junction) target. This is because all fileinfo
614 * on a Junction always returns the junction, opening the target
615 * is the only way to resolve the target's attributes.
616 */
617 if ((ident_rv = resolve_ident(finfo, fname, wanted, pool))
618 == APR_SUCCESS)
619 return ident_rv;
620 else if (ident_rv == APR_INCOMPLETE)
621 wanted &= ~finfo->valid;
622 }
623
624 if ((rv = utf8_to_unicode_path(wfname, sizeof(wfname)
625 / sizeof(apr_wchar_t), fname)))
626 return rv;
627 if (!(wanted & APR_FINFO_NAME)) {
629 &FileInfo.i))
630 return apr_get_os_error();
631 }
632 else {
633 /* Guard against bogus wildcards and retrieve by name
634 * since we want the true name, and set aside a long
635 * enough string to handle the longest file name.
636 */
637 char tmpname[APR_FILE_MAX * 3 + 1];
639 if ((rv = test_safe_name(fname)) != APR_SUCCESS) {
640 return rv;
641 }
644 return apr_get_os_error();
646 finddata = 1;
647
649 FileInfo.w.cFileName)) {
650 return APR_ENAMETOOLONG;
651 }
653 }
654 }
655#endif
656#if APR_HAS_ANSI_FS
658 {
659 char *root = NULL;
660 const char *test = fname;
662 isroot = (root && *root && !(*test));
663
665 {
666 /* cannot use FindFile on a Win98 root, it returns \*
667 * GetFileAttributesExA is not available on Win95
668 */
670 &FileInfo.i)) {
671 return apr_get_os_error();
672 }
673 }
674 else if (isroot) {
675 /* This is Win95 and we are trying to stat a root. Lie.
676 */
678 {
679 finfo->pool = pool;
680 finfo->filetype = 0;
681 finfo->mtime = apr_time_now();
683 finfo->protection |= (finfo->protection << prot_scope_group)
684 | (finfo->protection << prot_scope_user);
688 return (wanted &= ~finfo->valid) ? APR_INCOMPLETE
689 : APR_SUCCESS;
690 }
691 else
693 }
694 else {
695 /* Guard against bogus wildcards and retrieve by name
696 * since we want the true name, or are stuck in Win95,
697 * or are looking for the root of a Win98 drive.
698 */
700 if ((rv = test_safe_name(fname)) != APR_SUCCESS) {
701 return rv;
702 }
705 return apr_get_os_error();
706 }
708 finddata = 1;
709 if (wanted & APR_FINFO_NAME) {
710 filename = apr_pstrdup(pool, FileInfo.n.cFileName);
711 }
712 }
713 }
714#endif
715
716 if (ident_rv != APR_INCOMPLETE) {
718 0, finddata, fname, wanted))
719 {
720 /* Go the extra mile to assure we have a file. WinNT/2000 seems
721 * to reliably translate char devices to the path '\\.\device'
722 * so go ask for the full path.
723 */
725 {
726#if APR_HAS_UNICODE_FS
729 if (GetFullPathNameW(wfname, sizeof(tmpname) / sizeof(apr_wchar_t),
730 tmpname, &tmpoff))
731 {
732 if (!wcsncmp(tmpname, L"\\\\.\\", 4)) {
733#else
734 /* Same initial logic as above, but
735 * only for WinNT/non-UTF-8 builds of APR:
736 */
737 char tmpname[APR_FILE_MAX];
738 char *tmpoff;
739 if (GetFullPathName(fname, sizeof(tmpname), tmpname, &tmpoff))
740 {
741 if (!strncmp(tmpname, "\\\\.\\", 4)) {
742#endif
743 if (tmpoff == tmpname + 4) {
744 finfo->filetype = APR_CHR;
745 }
746 /* For WHATEVER reason, CHR devices such as \\.\con
747 * or \\.\lpt1 *may*not* update tmpoff; in fact the
748 * resulting tmpoff is set to NULL. Guard against
749 * either case.
750 *
751 * This code is identical for wide and narrow chars...
752 */
753 else if (!tmpoff) {
754 tmpoff = tmpname + 4;
755 while (*tmpoff) {
756 if (*tmpoff == '\\' || *tmpoff == '/') {
757 break;
758 }
759 ++tmpoff;
760 }
761 if (!*tmpoff) {
762 finfo->filetype = APR_CHR;
763 }
764 }
765 }
766 }
767 else {
768 finfo->valid &= ~APR_FINFO_TYPE;
769 }
770
771 }
772 else {
773 finfo->valid &= ~APR_FINFO_TYPE;
774 }
775 }
776 finfo->pool = pool;
777 }
778
779 if (filename && !isroot) {
780 finfo->name = filename;
781 finfo->valid |= APR_FINFO_NAME;
782 }
783
784 if (wanted &= ~finfo->valid) {
785 /* Caller wants more than APR_FINFO_MIN | APR_FINFO_NAME */
786#if APR_HAS_UNICODE_FS
788 return more_finfo(finfo, wfname, wanted, MORE_OF_WFSPEC);
789#endif
790 return more_finfo(finfo, fname, wanted, MORE_OF_FSPEC);
791 }
792
793 return APR_SUCCESS;
794}
795
800{
801 DWORD flags;
802 apr_status_t rv;
803#if APR_HAS_UNICODE_FS
805#endif
806
807 /* Don't do anything if we can't handle the requested attributes */
810 return APR_SUCCESS;
811
812#if APR_HAS_UNICODE_FS
814 {
816 sizeof(wfname) / sizeof(wfname[0]),
817 fname)))
818 return rv;
820 }
821#endif
822#if APR_HAS_ANSI_FS
824 {
826 }
827#endif
828
829 if (flags == 0xFFFFFFFF)
830 return apr_get_os_error();
831
833 {
836 else
838 }
839
841 {
844 else
846 }
847
848#if APR_HAS_UNICODE_FS
850 {
852 }
853#endif
854#if APR_HAS_ANSI_FS
856 {
858 }
859#endif
860
861 if (rv == 0)
862 return apr_get_os_error();
863
864 return APR_SUCCESS;
865}
866
867
871{
873 apr_status_t rv;
874
878 if (!rv)
879 {
883
886 rv = apr_get_os_error();
887 else
888 {
892 rv = apr_get_os_error();
893 }
894
896 }
897
898 return rv;
899}
int n
Definition ap_regex.h:278
static APR_INLINE void FileTimeToAprTime(apr_time_t *result, FILETIME *input)
static APR_INLINE void AprTimeToFileTime(LPFILETIME pft, apr_time_t t)
apr_uint16_t apr_wchar_t
APR Error Codes.
APR File I/O Handling.
APR Miscellaneous library routines.
APR Strings library.
APR Time Library.
#define APR_EPATHWILD
Definition apr_errno.h:334
#define APR_EBADPATH
Definition apr_errno.h:332
#define APR_EGENERAL
Definition apr_errno.h:313
#define APR_ENAMETOOLONG
Definition apr_errno.h:655
#define APR_INCOMPLETE
Definition apr_errno.h:452
#define APR_ENOTIMPL
Definition apr_errno.h:476
#define APR_STATUS_IS_EACCES(s)
Definition apr_errno.h:1231
apr_file_t * fd
const char apr_ssize_t int flags
Definition apr_encode.h:168
#define ERROR_SUCCESS
Definition mod_isapi.h:240
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_isalpha(c)
Definition apr_lib.h:205
#define APR_FROM_OS_ERROR(e)
Definition apr_errno.h:1214
#define APR_SUCCESS
Definition apr_errno.h:225
#define apr_get_os_error()
Definition apr_errno.h:1217
int apr_status_t
Definition apr_errno.h:44
#define APR_FILE_ATTR_READONLY
#define APR_FILE_ATTR_HIDDEN
apr_int32_t apr_fileperms_t
@ APR_PIPE
@ APR_LNK
@ APR_REG
@ APR_CHR
@ APR_DIR
apr_file_t * thefile
apr_uint32_t apr_fileattrs_t
const char apr_fileperms_t perms
apr_fileattrs_t attributes
apr_time_t mtime
apr_fileattrs_t apr_fileattrs_t attr_mask
#define APR_FOPEN_READ
Definition apr_file_io.h:54
#define APR_WREAD
#define APR_WWRITE
#define APR_WEXECUTE
#define APR_OS_DEFAULT
#define APR_FINFO_ATIME
#define APR_FINFO_OWNER
#define APR_FINFO_IDENT
const char apr_int32_t wanted
#define APR_FINFO_USER
const char * fname
#define APR_FINFO_NAME
#define APR_FINFO_GROUP
#define APR_FINFO_CTIME
#define APR_FINFO_MTIME
#define APR_FINFO_LINK
#define APR_FINFO_WPROT
#define APR_FINFO_NLINK
#define APR_FINFO_UPROT
#define APR_FINFO_TYPE
#define APR_FINFO_PROT
#define APR_FINFO_SIZE
#define APR_FINFO_GPROT
#define APR_FINFO_CSIZE
#define APR_FILEPATH_NATIVE
apr_size_t const char * filename
Definition apr_shm.h:72
apr_int64_t apr_time_t
Definition apr_time.h:45
gid_t apr_gid_t
Definition apr_user.h:54
return NULL
Definition mod_so.c:359
int i
Definition mod_so.c:347
#define IS_FNCHAR(c)
char * name
apr_pool_t * pool
apr_gid_t group
apr_filetype_e filetype
const char * name
apr_dev_t device
apr_off_t size
apr_pool_t * pool
apr_ino_t inode
struct apr_file_t * filehand
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
#define APR_OPENLINK
#define APR_OPENINFO
#define TRUSTEE_IS_WELL_KNOWN_GROUP
#define FILE_ATTRIBUTE_REPARSE_POINT
#define MORE_OF_HANDLE
#define MORE_OF_FSPEC
#define MORE_OF_WFSPEC
#define APR_FREADONLY
#define APR_FILE_MAX
#define FILE_ATTRIBUTE_DEVICE
#define APR_READCONTROL
#define APR_WRITEATTRS
#define GetNamedSecurityInfoW
#define ELSE_WIN_OS_IS_ANSI
typedef HANDLE(WINAPI *apr_winapi_fpt_CreateToolhelp32Snapshot)(DWORD dwFlags
#define GetFileAttributesExA
#define GetSecurityInfo
APR_DECLARE_DATA apr_oslevel_e apr_os_level
Definition misc.c:24
#define GetCompressedFileSizeA
@ APR_WIN_NT
@ APR_WIN_98
@ APR_WIN_2000
#define GetFileAttributesExW
#define ZwQueryInformationFile
#define IF_WIN_OS_IS_UNICODE
#define GetNamedSecurityInfoA
typedef DWORD(WINAPI *apr_winapi_fpt_GetCompressedFileSizeA)(IN LPCSTR lpFileName
#define GetCompressedFileSizeW
#define GetEffectiveRightsFromAclW
static apr_status_t resolve_ident(apr_finfo_t *finfo, const char *fname, apr_int32_t wanted, apr_pool_t *pool)
Definition filestat.c:142
static apr_fileperms_t convert_prot(ACCESS_MASK acc, prot_scope_e scope)
Definition filestat.c:75
apr_status_t more_finfo(apr_finfo_t *finfo, const void *ufile, apr_int32_t wanted, int whatfile)
Definition filestat.c:278
static apr_status_t test_safe_name(const char *name)
Definition filestat.c:33
static void free_world(void)
Definition filestat.c:60
int fillin_fileinfo(apr_finfo_t *finfo, WIN32_FILE_ATTRIBUTE_DATA *wininfo, int byhandle, int finddata, const char *fname, apr_int32_t wanted)
Definition filestat.c:417
static void resolve_prot(apr_finfo_t *finfo, apr_int32_t wanted, PACL dacl)
Definition filestat.c:91
prot_scope_e
Definition filestat.c:69
@ prot_scope_group
Definition filestat.c:71
@ prot_scope_world
Definition filestat.c:70
@ prot_scope_user
Definition filestat.c:72
static int reparse_point_is_link(WIN32_FILE_ATTRIBUTE_DATA *wininfo, int finddata, const char *fname)
Definition filestat.c:213
static apr_status_t free_localheap(void *heap)
Definition filestat.c:53
static apr_gid_t worldid
Definition filestat.c:58
static apr_status_t guess_protection_bits(apr_finfo_t *finfo, apr_int32_t wanted)
Definition filestat.c:191