]>
Commit | Line | Data |
---|---|---|
0c1992fb | 1 | /** @file\r |
2 | Implementation of the Posix access() function.\r | |
3 | \r | |
4 | Copyright (c) 2011, Intel Corporation. All rights reserved.<BR>\r | |
5 | This program and the accompanying materials are licensed and made available under\r | |
6 | the terms and conditions of the BSD License that accompanies this distribution.\r | |
7 | The full text of the license may be found at\r | |
8 | http://opensource.org/licenses/bsd-license.\r | |
9 | \r | |
10 | THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r | |
11 | WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r | |
12 | **/\r | |
13 | #include <LibConfig.h>\r | |
14 | #include <sys/EfiCdefs.h>\r | |
15 | \r | |
16 | #include <ctype.h>\r | |
17 | #include <errno.h>\r | |
18 | #include <sys/stat.h>\r | |
19 | #include <string.h>\r | |
20 | #include <unistd.h>\r | |
21 | #include <sys/syslimits.h>\r | |
22 | \r | |
23 | /** Save some typing later on. */\r | |
24 | #define GOOD_MODE (F_OK | X_OK | W_OK | R_OK)\r | |
25 | \r | |
26 | /** Determine accessibility of a file.\r | |
27 | The access() function checks the file, named by the pathname pointed to by\r | |
28 | the Path argument, for accessibility according to the bit pattern contained\r | |
29 | in Mode.\r | |
30 | \r | |
31 | The value of Mode is either the bitwise-inclusive OR of the access\r | |
32 | permissions to be checked (R_OK, W_OK, X_OK) or the existence test (F_OK).\r | |
33 | \r | |
34 | If Path ends in '/' or '\\', the target must be a directory, otherwise it doesn't matter.\r | |
35 | A file is executable if it is NOT a directory and it ends in ".efi".\r | |
36 | \r | |
37 | @param[in] Path Path or name of the file to be checked.\r | |
38 | @param[in] Mode Access permissions to check for.\r | |
39 | \r | |
40 | @retval 0 Successful completion.\r | |
41 | @retval -1 File is not accessible with the given Mode. The error condition\r | |
42 | is indicated by errno. Values of errno specific to the access\r | |
43 | function include: EACCES, ENOENT, ENOTDIR, ENAMETOOLONG\r | |
44 | **/\r | |
45 | int\r | |
46 | access(\r | |
47 | const char *Path,\r | |
48 | int Mode\r | |
49 | )\r | |
50 | {\r | |
51 | struct stat FileStat;\r | |
52 | int retval = -1;\r | |
53 | size_t PLength;\r | |
54 | uint32_t WantDir;\r | |
55 | uint32_t DirMatch;\r | |
56 | \r | |
57 | if((Path == NULL) || ((Mode & ~GOOD_MODE) != 0)) {\r | |
58 | errno = EINVAL;\r | |
59 | }\r | |
60 | else {\r | |
61 | PLength = strlen(Path);\r | |
62 | if(PLength > PATH_MAX) {\r | |
63 | errno = ENAMETOOLONG;\r | |
64 | }\r | |
65 | else {\r | |
66 | retval = stat(Path, &FileStat);\r | |
67 | if(retval == 0) {\r | |
68 | /* Path exists. FileStat now holds valid information. */\r | |
69 | WantDir = isDirSep(Path[PLength - 1]); // Does Path end in '/' or '\\' ?\r | |
70 | DirMatch = (! WantDir && (! S_ISDIR(FileStat.st_mode)));\r | |
71 | \r | |
72 | /* Test each permission individually. */\r | |
73 | do {\r | |
74 | if(Mode == F_OK) { /* Existence test. */\r | |
75 | if(DirMatch) { /* This is a directory or file as desired. */\r | |
76 | retval = 0;\r | |
77 | }\r | |
78 | else {\r | |
79 | /* Indicate why we failed the test. */\r | |
80 | errno = (WantDir) ? ENOTDIR : EISDIR;\r | |
81 | }\r | |
82 | break; /* F_OK does not combine with any other tests. */\r | |
83 | }\r | |
84 | if(Mode & R_OK) {\r | |
85 | if((FileStat.st_mode & READ_PERMS) == 0) {\r | |
86 | /* No read permissions.\r | |
87 | For UEFI, everything should have READ permissions.\r | |
88 | */\r | |
89 | errno = EDOOFUS; /* Programming Error. */\r | |
90 | break;\r | |
91 | }\r | |
92 | }\r | |
93 | if(Mode & W_OK) {\r | |
94 | if((FileStat.st_mode & WRITE_PERMS) == 0) {\r | |
95 | /* No write permissions. */\r | |
96 | errno = EACCES; /* Writing is not OK. */\r | |
97 | break;\r | |
98 | }\r | |
99 | }\r | |
100 | if(Mode & X_OK) {\r | |
101 | /* In EDK II, executable files end in ".efi" */\r | |
102 | if(strcmp(&Path[PLength-4], ".efi") != 0) {\r | |
103 | /* File is not an executable. */\r | |
104 | errno = EACCES;\r | |
105 | break;\r | |
106 | }\r | |
107 | }\r | |
108 | retval = 0;\r | |
109 | } while(FALSE);\r | |
110 | }\r | |
111 | else {\r | |
112 | /* File or path does not exist. */\r | |
113 | errno = ENOENT;\r | |
114 | }\r | |
115 | }\r | |
116 | }\r | |
117 | return retval;\r | |
118 | }\r |