rendered paste body#include <stdio.h>
#include <stdlib.h>
#include <errno.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <dirent.h>
#include <unistd.h>
#include <pwd.h>
#include <grp.h>
#define __DEBUG_
#ifdef __DEBUG_
#include <assert.h>
#define DEBUG(fmt, args...) printf(fmt, ## args)
#else
#define DEBUG(fmt, args...)
#endif
static void decode_permissions(mode_t perms, char *entry_perms)
{
if (S_ISDIR(perms))
entry_perms[0] = 'd';
/* .... */
if (perms & S_IRUSR)
entry_perms[1] = 'r';
if (perms & S_IWUSR)
entry_perms[2] = 'w';
if (perms & S_IXUSR)
entry_perms[3] = 'x';
if (perms & S_IRGRP)
entry_perms[4] = 'r';
if (perms & S_IWGRP)
entry_perms[5] = 'w';
if (perms & S_IXGRP)
entry_perms[6] = 'x';
if (perms & S_IROTH)
entry_perms[7] = 'r';
if (perms & S_IWOTH)
entry_perms[8] = 'w';
if (perms & S_IXOTH)
entry_perms[9] = 'x';
}
/* ${CC} -D_LARGEFILE_SOURCE -D_FILE_OFFSET_BITS=64 */
#define PERMISSIONS_LEN 10
static void show_dir_entry(const char *entry)
{
struct stat entry_stat;
char entry_perms[PERMISSIONS_LEN + 1] = "----------";
struct passwd *pwd;
struct group *grp;
if (entry) {
if (stat(entry, &entry_stat) == -1) {
perror("stat");
return;
}
decode_permissions(entry_stat.st_mode, entry_perms);
entry_perms[PERMISSIONS_LEN + 1] = '\0';
/* FIXME:
* functions getpwuid,getgrgid can return NULL
*/
pwd = getpwuid(entry_stat.st_uid);
grp = getgrgid(entry_stat.st_gid);
assert(pwd);
assert(grp);
printf("%s %ld\t %s %s %lld\t %.16s %s\n",
entry_perms,
(long) entry_stat.st_nlink,
grp->gr_name,
pwd->pw_name,
(long long)entry_stat.st_size,
ctime(&entry_stat.st_mtime),
entry);
} else {
/* BUG() */
}
}
static void show_dir(const char *path)
{
struct dirent **entry_list;
int n, i = 0;
n = scandir(path, &entry_list, 0, alphasort);
if (n < 0)
perror("scandir");
else {
if (chdir(path) == -1) {
perror("can't change directory");
return;
}
printf("%s\n", path);
while (i < n) {
show_dir_entry(entry_list[i]->d_name);
free(entry_list[i]);
i++;
}
free(entry_list);
}
}
static inline void show_file(const char *filename)
{
show_dir_entry(filename);
}
static void process_args(int argc, const char **argv)
{
int i;
struct stat st;
for (i = 1; i < argc; i++) {
if (stat(argv[i], &st) == -1) {
perror(argv[i]);
continue;
}
if (S_ISDIR(st.st_mode))
show_dir(argv[i]);
else if (S_ISREG(st.st_mode))
show_file(argv[i]);
/* ... */
else
printf("skipping...\n");
}
}
int main (int argc, char **argv)
{
if (argc == 1)
show_dir(".");
else
process_args(argc, argv);
return EXIT_SUCCESS;
}