Branch data Line data Source code
1 : : #include "precizer.h"
2 : : #include <errno.h>
3 : :
4 : : /**
5 : : * @brief Classify errno from a failed access() into FileAccessStatus
6 : : *
7 : : * Maps common filesystem errors to a stable, high-level status:
8 : : * - ENOENT, ENOTDIR -> FILE_NOT_FOUND
9 : : * - EACCES, EPERM -> FILE_ACCESS_DENIED
10 : : * - otherwise -> FILE_ACCESS_ERROR
11 : : *
12 : : * @param err errno value (typically `errno` after a failed `access()` call)
13 : : * @return FileAccessStatus classification
14 : : *
15 : : */
16 : 44 : static FileAccessStatus classify_access_errno(int err)
17 : : {
18 [ + + - + ]: 44 : if(err == ENOENT || err == ENOTDIR)
19 : : {
20 : 27 : return(FILE_NOT_FOUND);
21 : : }
22 : :
23 [ - + - - ]: 17 : if(err == EACCES || err == EPERM)
24 : : {
25 : 17 : return(FILE_ACCESS_DENIED);
26 : : }
27 : :
28 : 0 : return(FILE_ACCESS_ERROR);
29 : : }
30 : :
31 : : /**
32 : : * @brief Check access for a path, first as provided, then by its absolute form
33 : : *
34 : : * @details
35 : : * The function first calls `access()` for the path exactly as supplied
36 : : * If that succeeds, it returns `FILE_ACCESS_ALLOWED`
37 : : *
38 : : * If the initial call fails, the function then tries to construct an
39 : : * absolute path from `config->running_dir`
40 : : * When that fallback path can be built, the result is determined by the
41 : : * second `access()` call for the constructed absolute path
42 : : * If the fallback path cannot be built, the function returns
43 : : * `FILE_ACCESS_ERROR`
44 : : *
45 : : * @param path Path to check, relative or absolute
46 : : * @param path_size Length of the provided path
47 : : * @param mode Access mode for `access()` such as `R_OK` or `X_OK`
48 : : * @return `FILE_ACCESS_ALLOWED`, `FILE_ACCESS_DENIED`, `FILE_NOT_FOUND`, or
49 : : * `FILE_ACCESS_ERROR` based on the direct check or the fallback
50 : : * absolute-path check
51 : : */
52 : 16045 : FileAccessStatus file_check_access(
53 : : const char *path,
54 : : const size_t path_size,
55 : : const int mode)
56 : : {
57 [ + + ]: 16045 : if(access(path,mode) == 0)
58 : : {
59 : 1666 : return(FILE_ACCESS_ALLOWED);
60 : : }
61 : :
62 : : FileAccessStatus access_status;
63 : :
64 : 14379 : char *absolute_path = NULL;
65 : :
66 [ + - ]: 14379 : if(TRIUMPH & path_absolute_from_relative(&absolute_path,path,path_size))
67 : : {
68 [ + + ]: 14379 : if(access(absolute_path,mode) == 0)
69 : : {
70 : 14335 : access_status = FILE_ACCESS_ALLOWED;
71 : :
72 : : } else {
73 : :
74 : 44 : access_status = classify_access_errno(errno);
75 : : }
76 : : } else {
77 : 0 : access_status = FILE_ACCESS_ERROR;
78 : : }
79 : :
80 [ + - ]: 14379 : if(absolute_path != NULL)
81 : : {
82 : 14379 : free(absolute_path);
83 : : }
84 : :
85 : 14379 : return(access_status);
86 : : }
|