Line data Source code
1 : #include "precizer.h"
2 : #include <errno.h>
3 :
4 : /**
5 : * @brief Checks if a file is accessible for reading.
6 : *
7 : * This function verifies whether the specified file is readable.
8 : * If the direct access check fails, it attempts to resolve the absolute path
9 : * and checks again.
10 : *
11 : * @param[in] path Pointer to the file path string.
12 : * @param[in] path_size Pointer to the length of the path string.
13 : *
14 : * @return FileAccessStatus indicating accessibility, denial, or error.
15 : */
16 8521 : static FileAccessStatus classify_access_errno(int err)
17 : {
18 8521 : if(err == ENOENT || err == ENOTDIR)
19 : {
20 8507 : return(FILE_NOT_FOUND);
21 : }
22 :
23 14 : if(err == EACCES || err == EPERM)
24 : {
25 14 : return(FILE_ACCESS_DENIED);
26 : }
27 :
28 0 : return(FILE_ACCESS_ERROR);
29 : }
30 :
31 : /**
32 : * Check read access for a path, first as provided, then by its absolute form.
33 : *
34 : * The function preserves the errno classification from the initial `access`
35 : * call and only overwrites it if resolving the absolute path succeeds and a
36 : * second `access` call provides a more precise status.
37 : *
38 : * @param path Path to check (relative or absolute).
39 : * @param path_size Length of the provided path.
40 : * @return FILE_ACCESS_ALLOWED on success; FILE_NOT_FOUND, FILE_ACCESS_DENIED,
41 : * or FILE_ACCESS_ERROR depending on errno classification.
42 : */
43 9470 : FileAccessStatus file_check_access(
44 : const char *path,
45 : const size_t path_size)
46 : {
47 9470 : if(access(path,R_OK) == 0)
48 : {
49 985 : return(FILE_ACCESS_ALLOWED);
50 : }
51 :
52 8485 : FileAccessStatus access_status = classify_access_errno(errno);
53 :
54 8485 : char *absolute_path = NULL;
55 :
56 8485 : if(SUCCESS == path_absolute_from_relative(&absolute_path,path,path_size))
57 : {
58 8485 : if(access(absolute_path,R_OK) == 0)
59 : {
60 8449 : access_status = FILE_ACCESS_ALLOWED;
61 :
62 : } else {
63 :
64 36 : access_status = classify_access_errno(errno);
65 : }
66 : }
67 :
68 8485 : free(absolute_path);
69 :
70 8485 : return(access_status);
71 : }
|