<commit_before>/*
** Copyright 2002, <NAME>. All rights reserved.
** Distributed under the terms of the NewOS License.
*/
#include <sys/syscalls.h>
#include <stdio.h>
#include <string.h>

void (*disp_func)(const char *, struct file_stat *) = NULL;

static void display_l(const char *filename, struct file_stat *stat)
{
	const char *type;

	switch(stat->type) {
		case STREAM_TYPE_FILE:
			type = "FILE";
			break;
		case STREAM_TYPE_DEVICE:
			type = "DEV ";
			break;
		case STREAM_TYPE_DIR:
			type = "DIR ";
			break;
		case STREAM_TYPE_PIPE:
			type = "PIPE";
			break;
		default:
			type = "UNKN";
	}

	printf("%s %12Ld %s\n", type, stat->size, filename);
}

// unused
#if 0
static void display(const char *filename, struct file_stat *stat)
{
	printf("%s\n", filename);
}
#endif

int main(int argc, char *argv[])
{
	int rc;
	int rc2;
	int count = 0;
	struct file_stat stat;
	char *arg;

	if(argc == 1) {
		arg = ".";
	} else {
		arg = argv[1];
	}

	// for now, use the '-l' version of the display func
	disp_func = display_l;

	rc = sys_rstat(arg, &stat);
	if(rc < 0) {
		printf("sys_rstat() returned error: %s!\n", strerror(rc));
		goto err_ls;
	}

	switch(stat.type) {
		case STREAM_TYPE_DIR: {
			int fd;
			char buf[1024];

			fd = sys_open(arg, STREAM_TYPE_DIR, 0);
			if(fd < 0) {
				printf("ls: sys_open() returned error: %s!\n", strerror(fd));
				break;
			}

			for(;;) {
				char buf2[1024];

				rc = sys_read(fd, buf, -1, sizeof(buf));
				if(rc <= 0)
					break;

				buf2[0] = 0;
				if(strcmp(arg, ".") != 0) {
					strlcpy(buf2, arg, sizeof(buf2));
					strlcat(buf2, "/", sizeof(buf2));
				}
				strlcat(buf2, buf, sizeof(buf2));

				rc2 = sys_rstat(buf2, &stat);
				if(rc2 >= 0) {
					(*disp_func)(buf2, &stat);
				}
				count++;
			}
			sys_close(fd);

			printf("%d files found\n", count);
			break;
		}
		default:
			(*disp_func)(argv[1], &stat);
			break;
	}

err_ls:
	return 0;
}

<commit_msg>make 'ls' prettier and more useful<commit_after>/*
** Copyright 2002, <NAME>. All rights reserved.
** Distributed under the terms of the NewOS License.
*/
#include <sys/syscalls.h>
#include <stdio.h>
#include <string.h>
#include <stdlib.h>

/* globals */
void (*disp_func)(const char *, struct file_stat *) = NULL;
bool full_list = false;

static void display_l(const char *filename, struct file_stat *stat)
{
	const char *type;

	switch(stat->type) {
		case STREAM_TYPE_FILE:
			type = "FILE";
			break;
		case STREAM_TYPE_DEVICE:
			type = "DEV ";
			break;
		case STREAM_TYPE_DIR:
			type = "DIR ";
			break;
		case STREAM_TYPE_PIPE:
			type = "PIPE";
			break;
		default:
			type = "UNKN";
	}

	printf("%s %12Ld %s\n", type, stat->size, filename);
}

// unused
static void display(const char *filename, struct file_stat *stat)
{
	printf("%s\n", filename);
}

static void usage(const char *progname)
{
	printf("usage:\n");
	printf("%s [-al] [file ...]\n", progname);

	exit(1);
}

static int do_ls(const char *arg)
{
	int rc;
	int rc2;
	struct file_stat stat;
	int count = 0;

	rc = sys_rstat(arg, &stat);
	if(rc < 0) {
		printf("sys_rstat() returned error: %s!\n", strerror(rc));
		return rc;
	}

	switch(stat.type) {
		case STREAM_TYPE_DIR: {
			int fd;
			char filename[1024];
			bool done_dot, done_dotdot;

			fd = sys_open(arg, STREAM_TYPE_DIR, 0);
			if(fd < 0) {
				//printf("ls: sys_open() returned error: %s!\n", strerror(fd));
				break;
			}

			if(strcmp(arg, ".") != 0) {
				printf("%s:\n", arg);
			}

			if(full_list) {
				done_dot = done_dotdot = false;
			} else {
				done_dot = done_dotdot = true;
			}

			for(;;) {
				char full_path[1024];

				if(!done_dot) {
					strlcpy(filename, ".", sizeof(filename));
					done_dot = true;
				} else if(!done_dotdot) {
					strlcpy(filename, "..", sizeof(filename));
					done_dotdot = true;
				} else {
					rc = sys_read(fd, filename, -1, sizeof(filename));
					if(rc <= 0)
						break;
				}

				full_path[0] = 0;
				if(strcmp(arg, ".") != 0) {
					strlcpy(full_path, arg, sizeof(full_path));
					strlcat(full_path, "/", sizeof(full_path));
				}
				strlcat(full_path, filename, sizeof(full_path));

				rc2 = sys_rstat(full_path, &stat);
				if(rc2 >= 0) {
					(*disp_func)(filename, &stat);
				}
				count++;
			}
			sys_close(fd);

			printf("%d files found\n", count);
			break;
		}
		default:
			(*disp_func)(arg, &stat);
			break;
	}

	return 0;
}

int main(int argc, char *argv[])
{
	char c;

	disp_func = &display;

	while((c = getopt(argc, argv, "al")) >= 0) {
		switch(c) {
			case 'a':
				full_list = true;
				break;
			case 'l':
				disp_func = &display_l;
				break;
			default:
				usage(argv[0]);
		}
	}

	if(optind >= argc) {
		// no arguments to ls. ls the current dir
		do_ls(".");
	} else {
		for(; optind < argc; optind++) {
			do_ls(argv[optind]);
		}
	}

	return 0;
}


{'fraction_non_alphanumeric': 0.1736414740787008, 'fraction_numerical': 0.01561524047470331, 'mean_word_length': 3.006672226855713, 'pattern_counts': {'":': 0, '<': 19, '<?xml version=': 0, '>': 20, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '7169566', 'n_tokens_mistral': 2274, 'n_tokens_neox': 1893, 'n_words': 458}