| 
 | 1 | +/*******************************************************************************  | 
 | 2 | + * access()  checks whether the calling process can access the file pathname. If  | 
 | 3 | + * pathname is a symbolic link, it is dereferenced.  | 
 | 4 | + *  | 
 | 5 | + * The mode specifies the accessibility check(s) to be performed, and is either  | 
 | 6 | + * the value F_OK, or a mask consisting of the bitwise OR of one or more of R_OK,  | 
 | 7 | + * W_OK, and X_OK.  F_OK tests for the existence of the file. R_OK, W_OK, and  | 
 | 8 | + * X_OK  test whether the file exists and grants read, write, and execute permis‐  | 
 | 9 | + * sions, respectively.  | 
 | 10 | + *  | 
 | 11 | + * The check is done using the calling process's real UID and GID, rather than  | 
 | 12 | + * the effective IDs as is done when actually attempting an operation (e.g.,  | 
 | 13 | + * open(2)) on the file. Similarly, for the root user, the check uses the set of  | 
 | 14 | + * permitted capabilities rather than the set of effective capabilities; and for  | 
 | 15 | + * non-root users, the check uses an empty set of capabilities.  | 
 | 16 | + ******************************************************************************/  | 
 | 17 | + | 
 | 18 | +#include <stdlib.h>  | 
 | 19 | +#include <stdio.h>  | 
 | 20 | +#include <string.h>  | 
 | 21 | +#include <unistd.h>  | 
 | 22 | + | 
 | 23 | + | 
 | 24 | +void print_help(char *msg, int rc)  | 
 | 25 | +{  | 
 | 26 | +    if (msg != NULL) fprintf(stderr, "%s\n", msg);  | 
 | 27 | +    fprintf(stderr, "my_access -h\n");  | 
 | 28 | +    fprintf(stderr, "my_access -f file\n");  | 
 | 29 | +    fprintf(stderr, "my_access [-r] [-w] [-x] file\n");  | 
 | 30 | +    fprintf(stderr, "\t-h\tPrint this help message\n");  | 
 | 31 | +    fprintf(stderr, "\t-f\tTest for existence of file\n");  | 
 | 32 | +    fprintf(stderr, "\t-r\tTest whether effective user can read file\n");  | 
 | 33 | +    fprintf(stderr, "\t-w\tTest whether effective user can write file\n");  | 
 | 34 | +    fprintf(stderr, "\t-x\tTest whether effective user can execute file\n");  | 
 | 35 | +    exit(rc);  | 
 | 36 | +}  | 
 | 37 | + | 
 | 38 | +int my_access(const char *pathname, int mode)  | 
 | 39 | +{  | 
 | 40 | +}  | 
 | 41 | + | 
 | 42 | +int  | 
 | 43 | +main(int argc, char *argv[])  | 
 | 44 | +{  | 
 | 45 | +    int fname;                  /* Location of filename argument in argv[] */  | 
 | 46 | +    int opt;  | 
 | 47 | +    int f_mode = 0;             /* F_OK maps to zero (0) */  | 
 | 48 | +    int rwx_mode = 0;  | 
 | 49 | +    char *invalid_opt_msg_fmt = "'%c' is an invalid option";  | 
 | 50 | +    char *invalid_opt_msg;  | 
 | 51 | +    char *file_missing_msg = "file name is missing";  | 
 | 52 | +    char *conflict_args_msg = "specify either -f or a combination of -r -w -x";  | 
 | 53 | +      | 
 | 54 | +    invalid_opt_msg = malloc(strlen(invalid_opt_msg_fmt));  | 
 | 55 | +    while ((opt = getopt(argc, argv, ":hfrwx")) != -1)  | 
 | 56 | +    {  | 
 | 57 | +        switch (opt)  | 
 | 58 | +        {  | 
 | 59 | +            case 'f': f_mode = 1; break;  | 
 | 60 | +            case 'h': print_help(NULL, EXIT_SUCCESS); break;  | 
 | 61 | +            case 'r': rwx_mode |= R_OK; break;  | 
 | 62 | +            case 'w': rwx_mode |= W_OK; break;  | 
 | 63 | +            case 'x': rwx_mode |= X_OK; break;  | 
 | 64 | +            case '?':  | 
 | 65 | +                sprintf(invalid_opt_msg, invalid_opt_msg_fmt, (char)optopt);  | 
 | 66 | +                print_help(invalid_opt_msg, EXIT_FAILURE);  | 
 | 67 | +                break;  | 
 | 68 | +        }  | 
 | 69 | +    }  | 
 | 70 | +      | 
 | 71 | +    fname = optind;  | 
 | 72 | + | 
 | 73 | +    if (fname >= argc) print_help(file_missing_msg, EXIT_FAILURE);  | 
 | 74 | +    if (f_mode == 0)  | 
 | 75 | +    {  | 
 | 76 | +        if (rwx_mode == 0) print_help(conflict_args_msg, EXIT_FAILURE);  | 
 | 77 | +    }  | 
 | 78 | +    else  | 
 | 79 | +    {  | 
 | 80 | +        if (rwx_mode != 0) print_help(conflict_args_msg, EXIT_FAILURE);  | 
 | 81 | +    }  | 
 | 82 | + | 
 | 83 | +    exit(EXIT_SUCCESS);  | 
 | 84 | +}  | 
0 commit comments