Skip to content

Instantly share code, notes, and snippets.

@iggyvolz
Created July 2, 2020 06:49
Show Gist options
  • Save iggyvolz/c664e04f1849b7a020dd0226d09c781b to your computer and use it in GitHub Desktop.
Save iggyvolz/c664e04f1849b7a020dd0226d09c781b to your computer and use it in GitHub Desktop.
#define _XOPEN_SOURCE 700
#include <stdlib.h>
#include <unistd.h>
#include <ftw.h>
#include <stdio.h>
#include <string.h>
#include <sys/sysmacros.h>
char typechar(int typeflag)
{
switch(typeflag & S_IFMT) {
case S_IFLNK:
return 's';
case S_IFREG:
return 'f';
case S_IFDIR:
return 'd';
case S_IFCHR:
return 'c';
default:
return '?';
}
}
int nlinks = 0;
ino_t* links = NULL;
char** files = NULL;
int print_entry(const char *filepath, const struct stat *info,
const int typeflag, struct FTW *pathinfo)
{
const char *const filename = filepath + pathinfo->base;
char type = typechar(info->st_mode);
char* link = NULL;
// Check for duplicate hardlinks
if(type == 'f' && info->st_nlink > 1) {
// Search for links to see if we find a matching one
for(int i=0;i<nlinks;i++) {
if(info->st_ino == links[i]) {
// Found a matching hardlink
type = 'h';
// Overwrite link with the filename that we are pointing to
link=files[i];
break;
}
}
if(type != 'h') {
// This is the first instance of this inode, we must add it
links = realloc(links, sizeof(ino_t) * (nlinks+1));
files = realloc(files, sizeof(char*) * (nlinks+1));
links[nlinks] = info->st_ino;
files[nlinks] = malloc(strlen(filepath) + 1);
strcpy(files[nlinks], filepath);
nlinks++;
}
}
if(type == 's') {
// Resolve symlink
link = malloc(1024);
ssize_t length = readlink(filepath, link, 1023);
link[length] = 0; // Manually null-terminate string
}
printf("%s\t%06o\t%d\t%d\t%c\t", filepath, info->st_mode, info->st_uid, info->st_gid, type);
if(type == 'c') {
printf("%d,%d\n",major(info->st_rdev),minor(info->st_rdev));
} else if(link == NULL) {
printf("\n");
} else {
printf("%s\n", link);
}
if(type == 's') {
free(link);
}
return 0;
}
int main(int argc, char *argv[])
{
printf("#<file>\t<permissions>\t<owner>\t<group>\t<type>\t<extra>\n");
// https://stackoverflow.com/a/29402705 saved my life from programming this manually
return nftw(".", print_entry, 15, FTW_PHYS);
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment