summaryrefslogtreecommitdiff
path: root/userland/minibox/utilities
diff options
context:
space:
mode:
Diffstat (limited to 'userland/minibox/utilities')
-rw-r--r--userland/minibox/utilities/ascii.c30
-rw-r--r--userland/minibox/utilities/cat.c54
-rw-r--r--userland/minibox/utilities/echo.c30
-rw-r--r--userland/minibox/utilities/ed.c145
-rw-r--r--userland/minibox/utilities/include.h41
-rw-r--r--userland/minibox/utilities/init.c72
-rw-r--r--userland/minibox/utilities/ls.c42
-rw-r--r--userland/minibox/utilities/minibox.c15
-rw-r--r--userland/minibox/utilities/pwd.c12
-rw-r--r--userland/minibox/utilities/touch.c11
-rw-r--r--userland/minibox/utilities/wc.c106
-rw-r--r--userland/minibox/utilities/yes.c13
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;
+}