diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..1d92c05 --- /dev/null +++ b/.gitignore @@ -0,0 +1,2 @@ +.vscode +shperm \ No newline at end of file diff --git a/shperm.c b/shperm.c new file mode 100644 index 0000000..769b497 --- /dev/null +++ b/shperm.c @@ -0,0 +1,90 @@ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#define PERMISSION_USER 2 +#define PERMISSION_GROUP 1 +#define PERMISSION_OTHERS 0 + +void printPermission(char* path, int permissions, int uid, int gid) { + // print current path + printf("%s: ", path); + + // print user + struct passwd* user = getpwuid(uid); + printf("%s ", user->pw_name); + + // print group + struct group* group = getgrgid(gid); + printf("%s ", group->gr_name); + + // print permissions + char permissionStr[3][4] = {"---\0", "---\0", "---\0"}; + for (int i = 0; i < 9; i++) { + // clear out all permissions except the i'th bit + int tmpPermission = permissions & (1 << i); + + // read + if (tmpPermission & S_IRUSR + || tmpPermission & S_IRGRP + || tmpPermission & S_IROTH) { + permissionStr[i / 3][(8 - i) % 3] = 'r'; + } + + // write + if (tmpPermission & S_IWUSR + || tmpPermission & S_IWGRP + || tmpPermission & S_IWOTH) { + permissionStr[i / 3][(8 - i) % 3] = 'w'; + } + + // execute + if (tmpPermission & S_IXUSR + || tmpPermission & S_IXGRP + || tmpPermission & S_IXOTH) { + permissionStr[i / 3][(8 - i) % 3] = 'x'; + } + } + printf("%s %s %s\n", permissionStr[PERMISSION_USER], permissionStr[PERMISSION_GROUP], permissionStr[PERMISSION_OTHERS]); +} + +int main(int argc, char* argv[]) { + if (argc != 2) { + fprintf(stderr, "Usage: %s \n", argv[0]); + exit(1); + } + + char* path; + path = malloc(PATH_MAX); + + if (realpath(argv[1], path)) { + printf("Realpath: %s\n", path); + + char* base; + do { + struct stat sb; + + base = basename(path); + if (stat(path, &sb) == 0) { + printPermission(path, sb.st_mode, sb.st_uid, sb.st_gid); + } else { + fprintf(stderr, "Error (%d): %s\n", errno, strerror(errno)); + exit(3); + } + + path = dirname(path); + } while (strcmp(base, "/")); + } else { + fprintf(stderr, "Error (%d): %s\n", errno, strerror(errno)); + exit(2); + } + + free(path); +} \ No newline at end of file