Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 3 additions & 2 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -116,6 +116,7 @@ mkfs/mkfs: mkfs/mkfs.c $K/fs.h $K/param.h
.PRECIOUS: %.o

UPROGS=\
$U/_man\
$U/_cat\
$U/_echo\
$U/_forktest\
Expand All @@ -133,8 +134,8 @@ UPROGS=\
$U/_wc\
$U/_zombie\

fs.img: mkfs/mkfs README.md $(UPROGS)
mkfs/mkfs fs.img README.md $(UPROGS)
fs.img: mkfs/mkfs README.md docs $(UPROGS)
mkfs/mkfs fs.img README.md docs $(UPROGS)

-include kernel/*.d user/*.d

Expand Down
Binary file removed docs/fogos.gif
Binary file not shown.
29 changes: 29 additions & 0 deletions docs/man.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
Instruction Page Manual: man()

NAME
man: An interface to systems reference manuals

SYNOPSIS
man[man options]

DESCRIPTION
Manual instruction framwork for various xv6 functions and programs. Man
allows for easy documentation and help within the operating system,
displaying the requested man page.

EXAMPLES
man - brings up the man page for man()

man ls - brings up the man page for ls()

man man -f grow - brings up the man page for man() then searchs for the
word "grow", showing only lines containing it

OPTIONS
-f - Flag for find

HISTORY
9/23/24 - Creation

AUTHOR
Written by Daniel Truong
93 changes: 91 additions & 2 deletions mkfs/mkfs.c
Original file line number Diff line number Diff line change
Expand Up @@ -4,12 +4,18 @@
#include <string.h>
#include <fcntl.h>
#include <assert.h>
#include <sys/types.h>
#include <dirent.h>
#include <sys/stat.h>

#define dirent xv6_dirent
#define stat xv6_stat // avoid clash with host struct stat
#include "kernel/types.h"
#include "kernel/fs.h"
#include "kernel/stat.h"
#include "kernel/param.h"
#undef dirent
#undef stat

#ifndef static_assert
#define static_assert(a, b) do { switch (0) case 0: case (a): ; } while (0)
Expand Down Expand Up @@ -65,12 +71,88 @@ xint(uint x)
return y;
}

void
add_file(int parent_fd, uint parentino, char *filename)
{
uint inum;
int fd;
char buf[BSIZE];
struct xv6_dirent de;

if((fd = openat(parent_fd, filename, 0)) < 0)
die(filename);

inum = ialloc(T_FILE);

bzero(&de, sizeof(de));
de.inum = xshort(inum);
strncpy(de.name, filename, DIRSIZ);
iappend(parentino, &de, sizeof(de));

ssize_t cc;
while((cc = read(fd, buf, sizeof(buf))) > 0)
iappend(inum, buf, cc);

close(fd);
}

uint
add_dir(int level, int parent_fd, uint parentino, char *dirname)
{
struct xv6_dirent de;
uint dino = ialloc(T_DIR);
bzero(&de, sizeof(de));
de.inum = xshort(dino);
strcpy(de.name, dirname);
iappend(parentino, &de, sizeof(de));

bzero(&de, sizeof(de));
de.inum = xshort(dino);
strcpy(de.name, ".");
iappend(dino, &de, sizeof(de));

bzero(&de, sizeof(de));
de.inum = xshort(parentino);
strcpy(de.name, "..");
iappend(dino, &de, sizeof(de));

int dir_fd = -1;
if ((dir_fd = openat(parent_fd, dirname, O_RDONLY)) == -1) {
perror("open");
return dino;
}

DIR *d = fdopendir(dir_fd);
if (d == NULL) {
perror("fdopendir");
return dino;
}

struct dirent *e;
while ((e = readdir(d)) != NULL) {
if (e->d_name[0] == '.') {
continue;
}

if (e->d_type == DT_REG) {
printf("%*s+ %s\n", level * 2, "", e->d_name);
add_file(dir_fd, dino, e->d_name);
} else if (e->d_type == DT_DIR) {
printf("%*s+ /%s\n", level * 2, "", e->d_name);
add_dir(level + 1, dir_fd, dino, e->d_name);
}
}
close(dir_fd);

return dino;
}

int
main(int argc, char *argv[])
{
int i, cc, fd;
uint rootino, inum, off;
struct dirent de;
struct xv6_dirent de;
char buf[BSIZE];
struct dinode din;

Expand All @@ -83,7 +165,7 @@ main(int argc, char *argv[])
}

assert((BSIZE % sizeof(struct dinode)) == 0);
assert((BSIZE % sizeof(struct dirent)) == 0);
assert((BSIZE % sizeof(struct xv6_dirent)) == 0);

fsfd = open(argv[1], O_RDWR|O_CREAT|O_TRUNC, 0666);
if(fsfd < 0)
Expand Down Expand Up @@ -128,6 +210,13 @@ main(int argc, char *argv[])
iappend(rootino, &de, sizeof(de));

for(i = 2; i < argc; i++){
struct stat sb;
stat(argv[i], &sb);
if (S_ISDIR(sb.st_mode)) {
add_dir(0, AT_FDCWD, rootino, argv[i]);
continue;
}

// get rid of "user/"
char *shortname;
if(strncmp(argv[i], "user/", 5) == 0)
Expand Down
142 changes: 142 additions & 0 deletions user/man.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,142 @@
#include "kernel/types.h"
#include "kernel/stat.h"
#include "user/user.h"
#include "kernel/fcntl.h"
#include "stdbool.h"
#include "stddef.h"

/***
* Helped function for the find flag, seeing if the line contains the word
*
* @param line line to be read
* @return true if found, false if not
*/
bool
find(char* line, char* word)
{
int lineLen = strlen(line);
int wordLen = strlen(word);
int readableLen = lineLen - wordLen;
char *linePtr = line;
char *wordPtr = word;
int count = 0;

if(readableLen < 0)
return false;

for(int i = 0; i < readableLen; i++){
for(int j = 0; j < wordLen; j++){
if(linePtr[j] != wordPtr[j])
break;
count++;
}
if(count == wordLen)
return true;
linePtr++;
count = 0;
}
return false;
}

/***
* Concatenating function for strings, automatically appends the .md file extension
*
* @param dst destination string to concatenate to
* @param src source string to concatenate from
*/
void
strcat(char *dst, char *src)
{
int startLen = strlen(dst);
int combLen = strlen(dst) + strlen(src) + 1;
int i = 0;

for(i = startLen; i < combLen ; i++){
dst[i] = src[i-startLen];
}

dst[i] = '\0';
}

/***
* Man command to print and afind man page
*
* @param path name of wanted manpage
* @param f flag for find functionality
* @param word word wanted to be found
*/
void
man(char *path, bool f, char *word)
{
int i = 0;int foundLines = 0;
char *arg = path;
uint size = 256;
char *manPage = malloc(size);
if(manPage == NULL){
exit(0);
}

char manPath[128];
char suffix[] = ".md";
strcat(manPath, "docs/");
strcat(manPath, arg);
strcat(manPath, suffix);

int fd = open(manPath, O_RDONLY);
if(fd <= 0){
printf("Man error: %s\nNo such man page exists\n", manPath);
exit(0);
}

while(true){
int bytes = getline(&manPage, &size, fd);
i++;

if(f == false){
printf("%s", manPage);
}else if(find(manPage, word)){
printf("%d:%s", i, manPage);
foundLines++;
}

if(bytes <= 0){
break;
}
}

if(f == true && foundLines == 0)
printf("%s not found in man page", word);

printf("\n");
free(manPage);
}

int
main(int argc, char *argv[])
{
if(argc > 1 && strlen(argv[1]) + 8 > 128){
printf("Man error: Argument exceeds path limit\n");
exit(0);
}if(argc > 4){
printf("Man error: Too many arguments, limit of 4\n");
exit(0);
}if(argc > 2 && strcmp(argv[2], "-f") != 0){
printf("Man error: Unknown Flag\n");
exit(0);
}if(argc == 3){
printf("Man error: Term needed for find\n");
exit(0);
}

if(argc < 2){
man("man", false, NULL);
exit(0);
}else if(argc == 2){
man(argv[1], false, NULL);
}else if(argc == 4){
man(argv[1], true, argv[3]);
}

exit(0);
}