diff options
Diffstat (limited to 'userland/minibox/utilities')
-rw-r--r-- | userland/minibox/utilities/ascii.c | 30 | ||||
-rw-r--r-- | userland/minibox/utilities/cat.c | 54 | ||||
-rw-r--r-- | userland/minibox/utilities/echo.c | 30 | ||||
-rw-r--r-- | userland/minibox/utilities/ed.c | 145 | ||||
-rw-r--r-- | userland/minibox/utilities/include.h | 41 | ||||
-rw-r--r-- | userland/minibox/utilities/init.c | 72 | ||||
-rw-r--r-- | userland/minibox/utilities/ls.c | 42 | ||||
-rw-r--r-- | userland/minibox/utilities/minibox.c | 15 | ||||
-rw-r--r-- | userland/minibox/utilities/pwd.c | 12 | ||||
-rw-r--r-- | userland/minibox/utilities/touch.c | 11 | ||||
-rw-r--r-- | userland/minibox/utilities/wc.c | 106 | ||||
-rw-r--r-- | userland/minibox/utilities/yes.c | 13 |
12 files changed, 571 insertions, 0 deletions
diff --git a/userland/minibox/utilities/ascii.c b/userland/minibox/utilities/ascii.c new file mode 100644 index 0000000..53429dc --- /dev/null +++ b/userland/minibox/utilities/ascii.c @@ -0,0 +1,30 @@ +#include <stdio.h> + +const char * const ascii_table[] = +{ +"Dec Hex Dec Hex Dec Hex Dec Hex Dec Hex Dec Hex Dec Hex Dec Hex", +" 0 00 NUL 16 10 DLE 32 20 48 30 0 64 40 @ 80 50 P 96 60 ` 112 70 p", +" 1 01 SOH 17 11 DC1 33 21 ! 49 31 1 65 41 A 81 51 Q 97 61 a 113 71 q", +" 2 02 STX 18 12 DC2 34 22 \" 50 32 2 66 42 B 82 52 R 98 62 b 114 72 r", +" 3 03 ETX 19 13 DC3 35 23 # 51 33 3 67 43 C 83 53 S 99 63 c 115 73 s", +" 4 04 EOT 20 14 DC4 36 24 $ 52 34 4 68 44 D 84 54 T 100 64 d 116 74 t", +" 5 05 ENQ 21 15 NAK 37 25 % 53 35 5 69 45 E 85 55 U 101 65 e 117 75 u", +" 6 06 ACK 22 16 SYN 38 26 & 54 36 6 70 46 F 86 56 V 102 66 f 118 76 v", +" 7 07 BEL 23 17 ETB 39 27 ' 55 37 7 71 47 G 87 57 W 103 67 g 119 77 w", +" 8 08 BS 24 18 CAN 40 28 ( 56 38 8 72 48 H 88 58 X 104 68 h 120 78 x", +" 9 09 HT 25 19 EM 41 29 ) 57 39 9 73 49 I 89 59 Y 105 69 i 121 79 y", +" 10 0A LF 26 1A SUB 42 2A * 58 3A : 74 4A J 90 5A Z 106 6A j 122 7A z", +" 11 0B VT 27 1B ESC 43 2B + 59 3B ; 75 4B K 91 5B [ 107 6B k 123 7B {", +" 12 0C FF 28 1C FS 44 2C , 60 3C < 76 4C L 92 5C \\ 108 6C l 124 7C |", +" 13 0D CR 29 1D GS 45 2D - 61 3D = 77 4D M 93 5D ] 109 6D m 125 7D }", +" 14 0E SO 30 1E RS 46 2E . 62 3E > 78 4E N 94 5E ^ 110 6E n 126 7E ~", +" 15 0F SI 31 1F US 47 2F / 63 3F ? 79 4F O 95 5F _ 111 6F o 127 7F DEL", +}; + +int ascii_main(int argc, char ** argv) +{ + for(int i = 0;i < sizeof(ascii_table)/sizeof(ascii_table[0]);i++) + puts(ascii_table[i]); + + return 0; +} diff --git a/userland/minibox/utilities/cat.c b/userland/minibox/utilities/cat.c new file mode 100644 index 0000000..c528d49 --- /dev/null +++ b/userland/minibox/utilities/cat.c @@ -0,0 +1,54 @@ +// cat - concatenate and print files +// https://pubs.opengroup.org/onlinepubs/9699919799/ +// +// TODO: Add -u flag "Write bytes from the input file to the standard +// output without delay as each is read." +#include "include.h" +#include <dirent.h> +#include <fcntl.h> +#include <stdio.h> +#include <string.h> +#include <unistd.h> + +int fd_to_stdout(int fd) { + int rc; + for (char buffer[CAT_BUFFER]; (rc = read(fd, &buffer, sizeof(buffer)));) { + if (-1 == rc) + return 0; + if (-1 == write(fd_stdout, buffer, rc)) + return 0; + } + return 1; +} + +int cat_main(int argc, char **argv) { + int fd = fd_stdin; + + // If no file operands are specified, the standard input shall be + // used. + if (argc < 2) { + return (fd_to_stdout(0)) ? 0 : 1; + } + + argv++; + for (; *argv; argv++) { + // If a file is '-', the cat utility shall read from the standard + // input at that point in the sequence. + if (0 == strcmp(*argv, "-")) { + if (!fd_to_stdout(0)) + return 1; + continue; + } + + if (-1 == (fd = open(*argv, O_RDONLY, 0))) { + printf("cat: "); + // fflush(stdout); + perror(*argv); + return 1; + } + if (!fd_to_stdout(fd)) + return 1; + close(fd); + } + return 0; +} diff --git a/userland/minibox/utilities/echo.c b/userland/minibox/utilities/echo.c new file mode 100644 index 0000000..5ec68a7 --- /dev/null +++ b/userland/minibox/utilities/echo.c @@ -0,0 +1,30 @@ +#include "include.h" +#include <fcntl.h> +#include <stdint.h> +#include <stdio.h> +#include <unistd.h> + +int echo(char **str, int new_line) { + for (; *str;) { + printf("%s", *str); + if (*++str) + putchar(' '); + } + + if (new_line) + putchar('\n'); + return 0; +} + +int echo_main(int argc, char **argv) { + int new_line = 1; + + for (; *++argv && '-' == **argv;) + switch (*(*argv + 1)) { + case 'n': + new_line = 0; + break; + } + + return echo(argv, new_line); +} diff --git a/userland/minibox/utilities/ed.c b/userland/minibox/utilities/ed.c new file mode 100644 index 0000000..53270dc --- /dev/null +++ b/userland/minibox/utilities/ed.c @@ -0,0 +1,145 @@ +// ed - edit text +// ed [-p string] [-s] [file] +#include <assert.h> +#include <stdio.h> +#include <string.h> +#define COMMAND_MODE 0 +#define INPUT_MODE 1 + +int mode = COMMAND_MODE; + +FILE *fp = NULL; +FILE *mem_fp = NULL; +int line_number = 1; + +int getline(char *buffer, size_t s) { + (void)s; + int i = 0; + char c; + for (;; i++) { + int rc = read(0, &c, 1); + assert(rc > 0); + printf("%c", c); + buffer[i] = c; + if ('\n' == c) + break; + } + buffer[i] = '\0'; + return i; +} + +void goto_line(void) { + char c; + fseek(mem_fp, 0, SEEK_SET); + int line = 1; + if (1 != line_number) { + // Goto line + for (; fread(&c, 1, 1, mem_fp);) { + if ('\n' == c) + line++; + if (line == line_number) + return; + } + printf("got to line: %d\n", line); + assert(0); + } +} + +void read_line(void) { + char c; + goto_line(); + for (; fread(&c, 1, 1, mem_fp);) { + if ('\n' == c) + break; + printf("%c", c); + } + printf("\n"); +} + +void goto_end_of_line(void) { + char c; + for (; fread(&c, 1, 1, mem_fp);) { + if ('\n' == c) + break; + } +} + +void delete_line(void) { + long s = ftell(mem_fp); + printf("s: %d\n", s); + goto_end_of_line(); + long end = ftell(mem_fp); + printf("end: %d\n", end); + long offset = end - s; + for (char buffer[4096];;) { + int rc = fread(buffer, 1, 100, mem_fp); + long reset = ftell(mem_fp); + if (0 == rc) + break; + fseek(mem_fp, s, SEEK_SET); + fwrite(buffer, 1, rc, mem_fp); + s += rc; + fseek(mem_fp, reset, SEEK_SET); + } +} + +void read_command(void) { + char buffer[4096]; + char *s = buffer; + getline(buffer, 4096); + int a = -1; + int rc = sscanf(buffer, "%d", &a); + if (0 < rc) { + line_number = a; + } + for (; isdigit(*s); s++) + ; + if (0 == strcmp(s, "i")) { + mode = INPUT_MODE; + return; + } + if (0 == strcmp(s, ".")) { + read_line(); + return; + } + return; +} + +void read_input(void) { + char buffer[4096]; + int l = getline(buffer, 4096); + if (0 == strcmp(buffer, ".")) { + mode = COMMAND_MODE; + return; + } + goto_line(); + delete_line(); + goto_line(); + assert(fwrite(buffer, l, 1, mem_fp)); + return; +} + +int ed_main(char argc, char **argv) { + if (argc < 2) + return 1; + char *buffer; + size_t size; + mem_fp = open_memstream(&buffer, &size); + assert(mem_fp); + fp = fopen(argv[1], "r"); + assert(fp); + char r_buffer[4096]; + for (int rc; (rc = fread(buffer, 1, 4096, fp));) { + fwrite(r_buffer, 1, rc, mem_fp); + } + + for (;;) { + if (COMMAND_MODE == mode) + read_command(); + else + read_input(); + } + fclose(fp); + fclose(mem_fp); + return 0; +} diff --git a/userland/minibox/utilities/include.h b/userland/minibox/utilities/include.h new file mode 100644 index 0000000..7ffd136 --- /dev/null +++ b/userland/minibox/utilities/include.h @@ -0,0 +1,41 @@ +#include <stdio.h> +/* General constants */ +#define fd_stdin 0 /* standard in file descriptor */ +#define fd_stdout 1 /* standard out file descriptor */ +#define ASSERT_NOT_REACHED assert(0); +/* END General constants */ + +/* CAT SETTINGS */ +#define CAT_BUFFER 4096 /* size of the read buffer */ +/* END CAT SETTINGS */ + +/* HTTP SETTINGS */ +#define HTTP_MAX_BUFFER 4096 /* size of the read buffer */ +#define HTTP_DEFAULT_PORT 1337 /* default port should -p not be supplied */ +#define HTTP_WEBSITE_ROOT "site/" /* default directory that it chroots into */ + +/* should xxx.html not exist these will be supplied instead */ +#define HTTP_DEFAULT_404_SITE "404 - Not Found" +#define HTTP_DEFAULT_400_SITE "400 - Bad Request" +/* END HTTP SETTINGS */ + +#define COND_PERROR_EXP(condition, function_name, expression) \ + if (condition) { \ + perror(function_name); \ + expression; \ + } + +int minibox_main(int argc, char **argv); +int ascii_main(int argc, char **argv); +int echo_main(int argc, char **argv); +int http_main(int argc, char **argv); +int lock_main(int argc, char **argv); +int yes_main(int argc, char **argv); +int cat_main(int argc, char **argv); +int pwd_main(int argc, char **argv); +int wc_main(int argc, char **argv); +int ls_main(int argc, char **argv); +int touch_main(int argc, char **argv); +int ed_main(int argc, char **argv); + +int init_main(void); diff --git a/userland/minibox/utilities/init.c b/userland/minibox/utilities/init.c new file mode 100644 index 0000000..35bedf2 --- /dev/null +++ b/userland/minibox/utilities/init.c @@ -0,0 +1,72 @@ +#include <assert.h> +#include <fcntl.h> +#include <poll.h> +#include <pty.h> +#include <stdarg.h> +#include <stddef.h> +#include <stdint.h> +#include <stdio.h> +#include <unistd.h> + +int cmdfd; + +void execsh(void) { + char *argv[] = {NULL}; + execv("/sh", argv); +} + +void newtty(void) { + int m; + int s; + openpty(&m, &s, NULL, NULL, NULL); + int pid = fork(); + if (0 == pid) { + dup2(s, 0); + dup2(s, 1); + dup2(s, 2); + execsh(); + return; + } + close(s); + cmdfd = m; +} + +void shell() { + struct pollfd fds[2]; + fds[0].fd = cmdfd; + fds[0].events = POLLIN; + fds[0].revents = 0; + fds[1].fd = open("/dev/keyboard", O_RDONLY, 0); + fds[1].events = POLLIN; + fds[1].revents = 0; + for (;; fds[0].revents = fds[1].revents = 0) { + poll(fds, 2, 0); + if (fds[0].revents & POLLIN) { + char c[4096]; + int rc = read(fds[0].fd, c, 4096); + assert(rc > 0); + for (int i = 0; i < rc; i++) + putchar(c[i]); + } + if (fds[1].revents & POLLIN) { + char c; + int rc = read(fds[1].fd, &c, 1); + assert(rc > 0); + write(cmdfd, &c, 1); + // putchar(c); + } + } +} + +int init_main(void) { + if (1 != getpid()) { + printf("minibox init must be launched as pid1.\n"); + return 1; + } + if (fork()) + for (;;) + wait(NULL); + char *a[] = {NULL}; + execv("/term", a); + return 1; +} diff --git a/userland/minibox/utilities/ls.c b/userland/minibox/utilities/ls.c new file mode 100644 index 0000000..dc93d36 --- /dev/null +++ b/userland/minibox/utilities/ls.c @@ -0,0 +1,42 @@ +#include "include.h" +#include <dirent.h> +#include <fcntl.h> +#include <stdlib.h> +#include <string.h> +#include <sys/types.h> +#include <unistd.h> + +int ls_main(int argc, char **argv) { + int list_hidden = 0; + int newline = 0; + /* + for (int ch;-1 != (ch = getopt(argc, argv, "a1"));) + switch ((char)ch) + { + case 'a': + list_hidden = 1; + break; + case '1': + newline = 1; + break; + }*/ + struct dirent **namelist; + int n; + COND_PERROR_EXP(-1 == (n = scandir("/", &namelist, 0, 0)), "scandir", + return 1); + + int prev = 0; + for (int i = 0; i < n; i++) { + if (!list_hidden) + if ('.' == *namelist[i]->d_name) + continue; + + if (prev) + putchar(newline ? '\n' : ' '); + else + prev = 1; + printf("%s", namelist[i]->d_name); + } + putchar('\n'); + return 0; +} diff --git a/userland/minibox/utilities/minibox.c b/userland/minibox/utilities/minibox.c new file mode 100644 index 0000000..ec5fdbd --- /dev/null +++ b/userland/minibox/utilities/minibox.c @@ -0,0 +1,15 @@ +#include "include.h" + +void usage(void); +int main(int argc, char **argv); + +// Should a command be called via "minibox <command> <arguments>" then shift +// argv and argc to become "<command> <arguments>" and rerun main() +int minibox_main(int argc, char **argv) { + if (argc < 2) + usage(); + + argc--; + argv++; + return main(argc, argv); +} diff --git a/userland/minibox/utilities/pwd.c b/userland/minibox/utilities/pwd.c new file mode 100644 index 0000000..29d8129 --- /dev/null +++ b/userland/minibox/utilities/pwd.c @@ -0,0 +1,12 @@ +#include "include.h" +#include <stdio.h> +#include <stdlib.h> +#include <unistd.h> +#include <limits.h> + +int pwd_main(int argc, char **argv) { + char cwd[PATH_MAX]; + COND_PERROR_EXP(NULL == (getcwd(cwd, PATH_MAX)), "getcwd", return 1); + puts(cwd); + return 0; +} diff --git a/userland/minibox/utilities/touch.c b/userland/minibox/utilities/touch.c new file mode 100644 index 0000000..949ad96 --- /dev/null +++ b/userland/minibox/utilities/touch.c @@ -0,0 +1,11 @@ +#include "include.h" +#include <fcntl.h> + +int touch_main(int argc, char **argv) { + if (argc < 2) + return 1; + int fd; + COND_PERROR_EXP(open(argv[1], 0, O_CREAT), "open", return 1) + close(fd); + return 0; +} diff --git a/userland/minibox/utilities/wc.c b/userland/minibox/utilities/wc.c new file mode 100644 index 0000000..886eb9e --- /dev/null +++ b/userland/minibox/utilities/wc.c @@ -0,0 +1,106 @@ +#include <stdio.h> +#include <unistd.h> +#include <stdlib.h> +#include <fcntl.h> +#include <ctype.h> +#include "include.h" + +int cmode, wmode, lmode; + +void output(const char * str, size_t lines, size_t words, size_t chars) +{ + if(lmode) + printf("%d", lines); + + if(wmode) + { + if(lmode) putchar(' '); + + printf("%d", words); + } + + if(cmode) + { + if(lmode) putchar(' '); + + printf("%d", chars); + } + + if(str) printf(" %s", str); + + putchar('\n'); +} + +void wc(int argc, char ** argv) +{ + int fd = fd_stdin; + size_t total_chars, total_words, total_lines; + total_chars = total_words = total_lines = 0; + + if(NULL == *argv) + goto read_stdin; + + + for(;*argv;argv++) + { + int new_word = 1; + size_t chars = 0, + words = chars, + lines = chars; + + fd = open(*argv, O_RDONLY, 0); +read_stdin: + for(char c;read(fd, &c, 1);) + { + if(cmode) + chars++; + + if(wmode) + { + if(isspace(c)) { + new_word = 1; + } else if(new_word) { + words++; + new_word = 0; + } + } + + if(lmode) + if('\n' == c) + lines++; + } + close(fd); + if(lmode) total_lines += lines; + if(wmode) total_words += words; + if(cmode) total_chars += chars; + + output(*argv, lines, words, chars); + if(NULL == *argv) return; // We read from stdin + } + + if(argc > 1) output("total", total_lines, total_words, total_chars); +} + +int wc_main(int argc, char ** argv) +{ + cmode = wmode = lmode = 0; + for(argc--;*++argv && '-' == **argv;argc--) + switch(*(*argv+1)) + { + case 'l': + lmode = 1; + break; + case 'w': + wmode = 1; + break; + case 'c': + cmode = 1; + break; + } + + if(!(lmode || cmode || wmode)) + cmode = wmode = lmode = 1; + + wc(argc, argv); + return 0; +} diff --git a/userland/minibox/utilities/yes.c b/userland/minibox/utilities/yes.c new file mode 100644 index 0000000..ff19004 --- /dev/null +++ b/userland/minibox/utilities/yes.c @@ -0,0 +1,13 @@ +#include "include.h" +#include <stdio.h> + +int yes_main(int argc, char **argv) { + if (argc < 2) + for (;;) + puts("y"); + + for (;; putchar('\n')) + for (int i = 1; i < argc; i++) + printf("%s ", argv[i]); + return 0; +} |