Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #include <stdio.h>
- #include <stdlib.h>
- #include <dirent.h>
- #include <sys/stat.h>
- #include <time.h>
- #include <string.h>
- #include <pwd.h>
- #include <grp.h>
- #define COL_USER 0
- #define COL_GRP 1
- #define COL_NLINKS 2
- #define COL_SZ 3
- #define NUM_COLS 4
- unsigned int col_width[NUM_COLS];
- char format[256];
- typedef char TFilename[256];
- void prepare_fmt()
- {
- sprintf(format, "%%s %%%dlu %%%ds %%%ds %%%dd %%s %%s\n", col_width[COL_NLINKS], col_width[COL_USER], col_width[COL_GRP], col_width[COL_SZ]);
- }
- void measure_columns(const char* f_name, const char* full_path)
- {
- struct stat st;
- if (stat(full_path, &st) == 0)
- {
- char time_str[20];
- strftime(time_str, 20, "%F %R", (localtime(&st.st_ctime)));
- struct passwd *pw = getpwuid(st.st_uid);
- struct group *grp = getgrgid(st.st_gid);
- unsigned int user_len = strlen(pw->pw_name);
- unsigned int grp_len = strlen(grp->gr_name);
- if (user_len > col_width[COL_USER])
- col_width[COL_USER] = user_len;
- if (grp_len > col_width[COL_GRP])
- col_width[COL_GRP] = grp_len;
- unsigned int size_len;
- unsigned int links_len;
- unsigned int div;
- links_len = 2;
- for (div = 10; div != 1000000; div *= 10, links_len++)
- {
- if (st.st_nlink / div == 0) break;
- }
- if (links_len > col_width[COL_NLINKS])
- col_width[COL_NLINKS] = links_len;
- size_len = 2;
- for (div = 10; div != 1000000000; div *= 10, size_len++)
- {
- if (st.st_size / div == 0) break;
- }
- if (size_len > col_width[COL_SZ])
- col_width[COL_SZ] = size_len;
- }
- else
- {
- printf("Error: problem with stat()\n");
- }
- }
- void show_info(const char* f_name, const char* full_path)
- {
- char mod_val[11] = {0};
- struct stat st;
- if (stat(full_path, &st) == 0)
- {
- mode_t perm = st.st_mode;
- mod_val[0] = ' ';
- if (S_ISDIR(st.st_mode))
- {
- mod_val[0] = 'd';
- }
- else if (S_ISREG(st.st_mode))
- {
- mod_val[0] = ' ';
- }
- else if (S_ISLNK(st.st_mode))
- {
- mod_val[0] = 'l';
- }
- mod_val[1] = (perm & S_IRUSR) ? 'r' : '-';
- mod_val[2] = (perm & S_IWUSR) ? 'w' : '-';
- mod_val[3] = (perm & S_IXUSR) ? 'x' : '-';
- mod_val[4] = (perm & S_IRGRP) ? 'r' : '-';
- mod_val[5] = (perm & S_IWGRP) ? 'w' : '-';
- mod_val[6] = (perm & S_IXGRP) ? 'x' : '-';
- mod_val[7] = (perm & S_IROTH) ? 'r' : '-';
- mod_val[8] = (perm & S_IWOTH) ? 'w' : '-';
- mod_val[9] = (perm & S_IXOTH) ? 'x' : '-';
- mod_val[10] = '\0';
- char time_str[20];
- strftime(time_str, 20, "%F %R", (localtime(&st.st_ctime)));
- struct passwd *pw = getpwuid(st.st_uid);
- struct group *grp = getgrgid(st.st_gid);
- printf(format,
- mod_val,
- st.st_nlink,
- pw->pw_name,
- grp->gr_name,
- st.st_size,
- time_str,
- f_name);
- }
- else
- {
- printf("Error: problem with stat()\n");
- }
- }
- int cmpfunc(const void* a, const void* b)
- {
- char *la, *lb;
- la = (char*)a;
- lb = (char*)b;
- return strcmp(la, lb);
- }
- void process_dir(const char * d_name)
- {
- DIR *folder;
- struct dirent *entry;
- unsigned int num = 0;
- unsigned int num_entries = 0;
- TFilename *filenames;
- folder = opendir(d_name);
- if (!folder)
- {
- perror("Unable to read directory");
- perror(d_name);
- return ;
- }
- while ((entry = readdir(folder)))
- {
- if (!strcmp(entry->d_name, ".")) continue;
- if (!strcmp(entry->d_name, "..")) continue;
- num_entries++;
- }
- closedir(folder);
- if (!num_entries) return;
- folder = opendir(d_name);
- if (!folder)
- {
- perror("Unable to read directory");
- perror(d_name);
- return ;
- }
- filenames = calloc(num_entries, sizeof(TFilename));
- if(filenames)
- {
- while ((entry = readdir(folder)) && (num < num_entries))
- {
- if (!strcmp(entry->d_name, ".")) continue;
- if (!strcmp(entry->d_name, "..")) continue;
- strcpy(filenames[num], entry->d_name);
- num++;
- }
- qsort(filenames, num, sizeof(TFilename), cmpfunc);
- printf("Total: %d\n", num);
- for (int i=0; i<num; ++i)
- {
- char path[256];
- strcpy(path, d_name);
- strcat(path, "/");
- strcat(path, filenames[i]);
- measure_columns(filenames[i], path);
- }
- prepare_fmt();
- for (int i=0; i<num; ++i)
- {
- char path[256];
- strcpy(path, d_name);
- strcat(path, "/");
- strcat(path, filenames[i]);
- show_info(filenames[i], path);
- }
- free(filenames);
- }
- closedir(folder);
- }
- int main(int argc, char* argv[])
- {
- if (argc > 1)
- {
- for (int i = 1; i < argc; i++)
- {
- char* arg = argv[i];
- struct stat st;
- if (stat(arg, &st) == 0)
- {
- if (S_ISDIR(st.st_mode))
- {
- printf("%s:\n", arg);
- process_dir(arg);
- printf("\n");
- }
- else
- {
- measure_columns(arg, arg);
- prepare_fmt();
- show_info(arg, arg);
- }
- }
- }
- }
- else
- {
- process_dir(".");
- }
- return 0;
- }
Add Comment
Please, Sign In to add comment