C File System Exploration: Data Structures and Directory Listing
C File System Exploration
This document details the implementation of a file system exploration tool in C. It includes data structures, permission handling, and directory listing functionalities.
Data Structures
The following constants and structures are defined:
MAX_PATH
: Maximum path length (150).MAX_NOMBRE
: Maximum file name length (32).MAX_FICHEROS
: Maximum number of files (500).
The datosF
structure stores file information:
struct datosF {
char name[MAX_NOMBRE];
long size;
long inode;
char *user;
char *group;
char permission[10];
};
Permission Handling
The damePermisos
function converts file mode permissions to a string:
char *damePermisos(mode_t st_mode) {
char *permission = malloc(10);
strcpy(permission, "----------");
if ((st_mode & S_IFDIR) == S_IFDIR) permission[0] = 'd';
if ((S_IRUSR & st_mode) == S_IRUSR) permission[1] = 'r';
if ((S_IWUSR & st_mode) == S_IWUSR) permission[2] = 'w';
if ((S_IXUSR & st_mode) == S_IXUSR) permission[3] = 'x';
if ((S_IRGRP & st_mode) == S_IRGRP) permission[4] = 'r';
if ((S_IWGRP & st_mode) == S_IWGRP) permission[5] = 'w';
if ((S_IXGRP & st_mode) == S_IXGRP) permission[6] = 'x';
if ((S_IROTH & st_mode) == S_IROTH) permission[7] = 'r';
if ((S_IWOTH & st_mode) == S_IWOTH) permission[8] = 'w';
if ((S_IXOTH & st_mode) == S_IXOTH) permission[9] = 'x';
return permission;
}
Sorting Functions
The following functions are used for sorting file data:
ordenaTamano_maM
: Sorts by size (ascending).ordenaTamano_Mam
: Sorts by size (descending).ordenaNombre
: Sorts by name (ascending).ordenaNombre_Inv
: Sorts by name (descending).
int ordenaTamano_maM(const void * _a, const void * _b) {
struct datosF a = * ((struct datosF *) _a);
struct datosF b = * ((struct datosF *) _b);
return (a.size - b.size);
}
int ordenaTamano_Mam(const void * _a, const void * _b) {
struct datosF a = * ((struct datosF *) _a);
struct datosF b = * ((struct datosF *) _b);
return (b.size - a.size);
}
int ordenaNombre(const void * _a, const void * _b) {
struct datosF a = * ((struct datosF *) _a);
struct datosF b = * ((struct datosF *) _b);
return strcmp(a.name, b.name);
}
int ordenaNombre_Inv(const void * _a, const void * _b) {
struct datosF a = * ((struct datosF *) _a);
struct datosF b = * ((struct datosF *) _b);
return strcmp(b.name, a.name);
}
Directory Listing Function
The do_ls
function lists directory contents with various options:
void do_ls(char *name, int opt_long, int opt_size, int opt_recursive, int opt_hidden, int opt_inode, int opt_sort_size, int opt_reverse) {
DIR *dir;
char path[MAX_PATH] = "";
char trayec_var[MAX_PATH] = "";
struct dirent *infodir;
struct datosF datosFichero[MAX_FICHEROS];
struct stat infoBuffer;
static int recursive = 0;
dir = opendir(name);
if (dir == NULL) {
perror("opendir error");
exit(1);
} else {
strcat(path, name);
if (recursive == 0) {
printf("\nlist %s with long format = %d, size = %d, recursive = %d, hidden = %d inode = %d sort_size = %d reverse = %d\n",
name, opt_long, opt_size, opt_recursive, opt_hidden, opt_inode, opt_sort_size, opt_reverse);
strcat(path, "/");
printf("\n----> We started by listing the elements of: %s", path);
}
infodir = readdir(dir);
int cont = 0;
while (infodir != NULL && cont < MAX_FICHEROS) {
strcpy(trayec_var, path);
strcat(trayec_var, infodir->d_name);
stat(trayec_var, &infoBuffer);
strcpy(datosFichero[cont].name, infodir->d_name);
datosFichero[cont].size = infoBuffer.st_size;
datosFichero[cont].inode = infoBuffer.st_ino;
datosFichero[cont].user = getpwuid(infoBuffer.st_uid)->pw_name;
datosFichero[cont].group = getgrgid(infoBuffer.st_gid)->gr_name;
strcpy(datosFichero[cont].permission, damePermisos(infoBuffer.st_mode));
infodir = readdir(dir);
cont++;
}
closedir(dir);
if (opt_sort_size == 1) {
if (opt_reverse == 1)
qsort(datosFichero, cont, sizeof(struct datosF), ordenaTamano_maM);
else
qsort(datosFichero, cont, sizeof(struct datosF), ordenaTamano_Mam);
} else {
if (opt_reverse == 1)
qsort(datosFichero, cont, sizeof(struct datosF), ordenaNombre_Inv);
else
qsort(datosFichero, cont, sizeof(struct datosF), ordenaNombre);
}
printf("\n");
for (int i = 0; i < cont; i++) {
if ((opt_hidden == 1) || (strcmp(datosFichero[i].name, ".") != 0 && strcmp(datosFichero[i].name, "..") != 0)) {
if (opt_inode == 1) {
printf("\t%ld\t", datosFichero[i].inode);
}
if (opt_long == 1) {
printf("\t%s", datosFichero[i].user);
printf("\t%s", datosFichero[i].group);
printf("\t%s", datosFichero[i].permission);
}
if (opt_size == 1) {
printf("\t%ld\t", datosFichero[i].size);
}
printf("%s\n", datosFichero[i].name);
if ((opt_recursive == 1) && (datosFichero[i].permission[0] == 'd')) {
recursive = 1;
strcpy(trayec_var, path);
strcat(trayec_var, datosFichero[i].name);
strcat(trayec_var, "/");
do_ls(trayec_var, opt_long, opt_size, opt_recursive, opt_hidden, opt_inode, opt_sort_size, opt_reverse);
int j = i + 1;
if (j < cont)
printf("<---- continue listing the elements of: %s\n", path);
}
}
}
}
}