All pastes #1767837 Raw Edit

Unnamed

public text v1 · immutable
#1767837 ·published 2010-01-27 11:09 UTC
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;
}