Reputation: 21
The context here is this is an university exercise. We're using C on a Linux Machine.
Using (I assume) stat()
, I need to make a function that works like access()
, by which I mean by sending a path and an octal number, it will check if the permission associated with said octal number are true for the real user or not.
int my_acess (const char *path, int mode)
I know that st_mode
contains the file mode, I just don't know how to actually use it. I'm assuming the last 3 digits I see are the ones referring to the mode so far, I got this done.
#include <stdlib.h>
#include <unistd.h>
#include <stdio.h>
#include <dirent.h>
#include <sys/stat.h>
#include <sys/syscall.h>
#include <sys/types.h>
#include <fcntl.h>
int my_acess (const char *path, int mode){
struct stat buf;
int check;
int f, f2;
int pmode;
check=stat(path, &buf);
if (check==-1) return -1;
//printf("%o\n",buf.st_mode%512); used this to examine how st_mode worked
pmode=buf.st_mode%512;
f=getuid();
f2=getgid();
if (f==buf.st_uid)
printf("you're the owner\n");
else if (f2==buf.st_gid)
printf("you're part of the group\n");
else
printf("you're other\n");
return -1;
}
Now that this part of the program is done... I just need to select the right octal number digit, which I'm not really sure how to do besides maybe dividing the octal number by 8 or 64?... convert both the octal numbers (pmode and mode) into binary (which I'm not sure if there's a "fast way" to do it besides just dividing by 2) and do an AND between each other and see if the resulting binary number is the same as the one in the variable mode (I don't even know if I need a special library for this).
This is how I think you're suppose to to implement this function, but maybe I'm overthinking it. Is there something I'm overlooking? A function or maybe a boolean macro that I forgot?
Upvotes: 0
Views: 116
Reputation: 5221
As described in the manual, st_mode field contains two information:
#define S_IRUSR __S_IREAD /* Read by owner. */
#define S_IWUSR __S_IWRITE /* Write by owner. */
#define S_IXUSR __S_IEXEC /* Execute by owner. */
/* Read, write, and execute by owner. */
#define S_IRWXU (__S_IREAD|__S_IWRITE|__S_IEXEC)
#define S_IRGRP (S_IRUSR >> 3) /* Read by group. */
#define S_IWGRP (S_IWUSR >> 3) /* Write by group. */
#define S_IXGRP (S_IXUSR >> 3) /* Execute by group. */
/* Read, write, and execute by group. */
#define S_IRWXG (S_IRWXU >> 3)
#define S_IROTH (S_IRGRP >> 3) /* Read by others. */
#define S_IWOTH (S_IWGRP >> 3) /* Write by others. */
#define S_IXOTH (S_IXGRP >> 3) /* Execute by others. */
/* Read, write, and execute by others. */
#define S_IRWXO (S_IRWXG >> 3)
So, if you need to check the type, you can write something like:
if (S_ISDIR(buf.st_mode)) {
// It is a directory
}
If you need to check the access bits:
if (buf.st_mode & S_IRUSR) {
// File readable by user
}
Upvotes: 1