diff --git a/README.md b/README.md index bde78a8..b4c01d1 100644 --- a/README.md +++ b/README.md @@ -5,8 +5,9 @@ License: wtfpl https://trivial.technology/ Unportable: - proc_parser + proc_parser.h ps + kill dmesg mount umount diff --git a/TODO b/TODO index 0d7d367..fdd121f 100644 --- a/TODO +++ b/TODO @@ -1,55 +1,33 @@ -With "micro-" prefix - *Todo: -tail expr uniq -od tr cut -shuf stty sort test tar sha* md5 - -Other: - sysctl - ping - ncat - ntpd - ifconfig - dhcp-client - getopt - fdisk - less - free - swapon - swapoff - hexdump - sed - -Loginutils: - usersctl - getty - -Modutils: - insmod - rmmod - lsmod - -Findutils: - grep - find - -BUGS: - ls (-l flag with long group/user name) - xargs (getopt with glibc) +sysctl +ping +ncat +ntpd +ifconfig +ipconfig +dhcp-client +getopt +fdisk +less +free +sed +usersctl +getty +insmod +rmmod +lsmod +grep +find FIX: - xargs (-d) echo (escape) - que (unicode) - ps (-o) diff --git a/build.sh b/build.sh index 11b029c..af27572 100755 --- a/build.sh +++ b/build.sh @@ -1,5 +1,4 @@ #!/bin/sh -./clean.sh if [ -z $CC ]; then CC="cc" @@ -9,7 +8,8 @@ if [ -z $CFLAGS ]; then CFLAGS="-s -Os -Wextra -Wall -pedantic" fi -chmod +x ./libmu/build-libmu.sh +chmod -v +x clean.sh ./scripts/build-box.sh ./libmu/build-libmu.sh +./clean.sh ./libmu/build-libmu.sh if [[ $1 == "box" ]]; then diff --git a/configs/config.h b/configs/config.h index 2d501ff..d8582eb 100644 --- a/configs/config.h +++ b/configs/config.h @@ -26,23 +26,6 @@ #define MOUNT_OPT_SIZE 512 #endif -#ifdef _LS_C - /* colors for ls */ - #define LS_DIR_COLOR "\033[1;34m" - #define LS_LINK_COLOR "\033[1;35m" - #define LS_SOCK_COLOR "\033[35m" - #define LS_FIFO_COLOR "\033[1;35m" - #define LS_BLOCK_COLOR "\033[1;33m" - #define LS_EXE_COLOR "\033[1;32m" -#endif - -#ifdef INIT - /* Init scripts */ - char *INIT_POWEROFF[] = {"/etc/rc.poweroff", NULL}; - char *INIT_START[] = {"/etc/rc.init", NULL}; - #define INIT_MSG "Starting micro-init..." -#endif - #ifdef _UNAME_C /* Os name for uname */ /* #define OS_NAME "unknow" */ diff --git a/scripts/build-box.sh b/scripts/build-box.sh index ba64c92..d64bbb2 100755 --- a/scripts/build-box.sh +++ b/scripts/build-box.sh @@ -50,5 +50,5 @@ int main(int argc, char **argv) { } EOF -echo $CFLAGS | xargs $CC -Iconfigs -Ilibmu mutils.c obj/*.o bin/*.c -o mutils +echo $CFLAGS | xargs $CC -D_BOX -Iconfigs -Ilibmu mutils.c obj/*.o bin/*.c -o mutils echo $CFLAGS | xargs $CC -Iconfigs scripts/musuid.c -o musuid diff --git a/src/bdname.c b/src/bdname.c index eeee9d1..d04e9c4 100644 --- a/src/bdname.c +++ b/src/bdname.c @@ -32,7 +32,7 @@ int main(int argc, char **argv) { break; default: - puts("bdname [sd] [str]\n\t-s SFX Set suffix\n\t-d Use dirname instead of basename"); + puts("bdname [sd] [str]\n\t-s STR Set suffix\n\t-d Use dirname instead of basename"); return 0; } } diff --git a/src/cat.c b/src/cat.c index 97e3696..58c7293 100644 --- a/src/cat.c +++ b/src/cat.c @@ -31,21 +31,12 @@ static int cat(const char *path) { } int main(int argc, char **argv) { - int opt; - while ((opt = getopt(argc, argv, "")) != -1) { - puts("cat [file1 file2...]"); - return 0; - } - - argv += optind; - argc -= optind; - - if (argc == 0) + if (argc == 1) return cat("-"); else { int ret = 0; - for (int i = 0; i < argc; i++) + for (int i = 1; i < argc; i++) if (cat(argv[i])) ret = 1; diff --git a/src/chgrp.c b/src/chgrp.c deleted file mode 100644 index 757a475..0000000 --- a/src/chgrp.c +++ /dev/null @@ -1,93 +0,0 @@ -#include -#include -#include -#include -#include -#include -#include -#include -#include "make_path.h" -#include "get_stat.h" -#include "recurse.h" - -static char r_flag; -static char *f_flag = "chgrp"; -static char H_flag; -static char v_flag; - -static int change(const char *path, void *p) { - struct group *grp = (struct group *)p; - - struct stat stat_path; - if (mu_get_stat(f_flag, path, &stat_path)) - return 1; - - if (lchown(path, stat_path.st_uid, grp->gr_gid)) { - if (f_flag) - fprintf(stderr, "chgrp: %s: %s\n", path, strerror(errno)); - - return 1; - } - - if (v_flag) - printf("chgrp: %s: changed group to %s\n", path, grp->gr_name); - - return 0; -} - -int main(int argc, char **argv) { - - int opt; - while ((opt = getopt(argc, argv, "RfHv")) != -1) { - switch (opt) { - case 'R': - r_flag = 1; - break; - - case 'f': - f_flag = NULL; - break; - - case 'H': - H_flag = 1; - break; - - case 'v': - v_flag = 1; - break; - - default: - puts("chgrp [RfHv] [group] [file1 file2...]\n\t-H Symbolic link\n\t-R Recursive\n\t-f Silent\n\t-v Verbose"); - return 0; - } - } - - argv += optind; - argc -= optind; - - if (argc == 0) { - fprintf(stderr, "chgrp: missing operand\n"); - return 1; - } - - struct group *grp = getgrnam(argv[0]); - if (!grp) { - if (f_flag) - fprintf(stderr, "chgrp: unknow group\n"); - - return 1; - } - - int ret = 0; - for (int i = 1; i < argc; i++) { - if (r_flag) { - if (mu_recurse(f_flag, H_flag, argv[i], (void *)grp, change, change)) - ret = 1; - } - - else - ret = change(argv[i], grp); - } - - return ret; -} diff --git a/src/chown.c b/src/chown.c index 6a05402..d34c6e4 100644 --- a/src/chown.c +++ b/src/chown.c @@ -12,18 +12,26 @@ #include "unused.h" static char r_flag; -static char *f_flag = "chown"; +static char *s_flag = "chown"; static char H_flag; static char v_flag; +static char g_flag; static int (*chown_func)(const char *pathname, uid_t owner, gid_t group); -static long gid; -static long uid; +static long gid = -1; +static long uid = -1; static int change(const char *path, void *p) { char *name = (char *)p; - if (chown_func(path, uid, gid)) { - if (f_flag) + struct stat sb; + if (mu_get_lstat(s_flag, path, &sb)) + return 1; + + long gid_priv = (gid == -1) ? sb.st_gid : gid; + long uid_priv = (uid == -1) ? sb.st_uid : uid; + + if (chown_func(path, uid_priv, gid_priv)) { + if (s_flag) fprintf(stderr, "chown: unable to chown %s: %s\n", path, strerror(errno)); return 1; @@ -35,25 +43,31 @@ static int change(const char *path, void *p) { return 0; } -static void get_owner(const char *arg) { +static void get_owner(char *arg) { char *group = strchr(arg, ':'); + char gg_flag = 1; + char gu_flag = 1; - char g_flag = 1; - char u_flag = 1; + if (group == NULL) { + if (g_flag) + gu_flag = 0; - if (group == arg) - u_flag = 0; + else + gg_flag = 0; + } - else if (!group) - g_flag = 0; + if (gg_flag) { + if (g_flag == 0) { + group[0] = '\0'; + group++; + } - if (g_flag) { - group[0] = '\0'; - group++; + else + group = arg; struct group *grp = getgrnam(group); if (!grp) { - if (f_flag) + if (s_flag) fprintf(stderr, "chown: invalid group: %s\n", group); exit(1); @@ -62,10 +76,10 @@ static void get_owner(const char *arg) { gid = grp->gr_gid; } - if (u_flag) { + if (gu_flag) { struct passwd *pwd = getpwnam(arg); if (!pwd) { - if (f_flag) + if (s_flag) fprintf(stderr, "chown: invalid user: %s\n", arg); exit(1); @@ -79,14 +93,14 @@ int main(int argc, char **argv) { chown_func = lchown; int opt; - while ((opt = getopt(argc, argv, "RfHv")) != -1) { + while ((opt = getopt(argc, argv, "RsHvg")) != -1) { switch (opt) { case 'R': r_flag = 1; break; - case 'f': - f_flag = NULL; + case 's': + s_flag = NULL; break; case 'H': @@ -98,8 +112,12 @@ int main(int argc, char **argv) { v_flag = 1; break; + case 'g': + g_flag = 1; + break; + default: - printf("chown [RfHf] USER[:[GRP]] [file1 file2...]\n\t-H Symbolic link\n\t-R Recursive\n\t-f Silent\n\t-v Verbose\n"); + puts("chown [RsHvg] USER[:[GRP]]/GRP [file1 file2...]\n\t-H Symbolic link\n\t-R Recursive\n\t-s Silent\n\t-v Verbose\n\t-g Change only group"); return 0; } } @@ -112,14 +130,12 @@ int main(int argc, char **argv) { return 1; } - gid = -1; - uid = -1; get_owner(argv[0]); int ret = 0; for (int i = 1; i < argc; i++) { if (r_flag) { - if (mu_recurse(f_flag, H_flag, argv[i], argv[0], change, change)) + if (mu_recurse(s_flag, H_flag, argv[i], argv[0], change, change)) ret = 1; } diff --git a/src/dmesg.c b/src/dmesg.c index 3d5c3be..6ad34ec 100644 --- a/src/dmesg.c +++ b/src/dmesg.c @@ -60,8 +60,6 @@ int main(int argc, char **argv) { if (write(STDOUT_FILENO, buf, n) != n) fprintf(stderr, "dmesg: %s\n", strerror(errno)); - putchar('\n'); - free(buf); return 0; } diff --git a/src/du.c b/src/du.c index abb0441..32c57eb 100644 --- a/src/du.c +++ b/src/du.c @@ -12,6 +12,7 @@ static char h_flag; static char s_flag; static char c_flag; +static char a_flag; static off_t total; static void print(off_t size, const char *filename) { @@ -67,13 +68,16 @@ static off_t du(const char *path, int recurs_flag) { else if (!recurs_flag) print(sum, path); + else if (a_flag && !s_flag) + print(sb.st_blocks, path); + return sum; } int main(int argc, char **argv) { int opt; - while ((opt = getopt(argc, argv, "hsc")) != -1) { + while ((opt = getopt(argc, argv, "hsca")) != -1) { switch (opt) { case 'h': h_flag = 1; @@ -87,8 +91,12 @@ int main(int argc, char **argv) { c_flag = 1; break; + case 'a': + a_flag = 1; + break; + default: - puts("du [hsc] [src1 src2...]\n\t-h Sizes in human readable format\n\t-s Display only a total for each argument\n\t-c produce a grand total"); + puts("du [hsca] [src1 src2...]\n\t-h Sizes in human readable format\n\t-s Display only a total for each argument\n\t-c produce a grand total\n\t-a Show file sizes too"); return 0; } } diff --git a/src/head.c b/src/head.c index a6a982c..c001080 100644 --- a/src/head.c +++ b/src/head.c @@ -45,7 +45,6 @@ static int print(const char *file, FILE *fp, long lines, long bytes) { long lmax = 0; long bmax = 0; - /* Make buffer */ size_t buf_size = 0; char *buf = malloc(1); if (buf == NULL) { @@ -54,11 +53,8 @@ static int print(const char *file, FILE *fp, long lines, long bytes) { } /* Fill buffer */ - while (1) { - int c = getc(fp); - if (c == EOF) - break; - + int c = 0; + while ((c = getc(fp)) != EOF) { char *tmp = realloc(buf, buf_size + 2); if (tmp == NULL) { fprintf(stderr, "%s: realloc: %s\n", PROG_NAME, strerror(errno)); @@ -79,12 +75,7 @@ static int print(const char *file, FILE *fp, long lines, long bytes) { /* Print buffer */ for (size_t i = 0; i < buf_size; i++) { - if (buf[i] == '\n') - lcount++; - - bcount++; - - if ((c_flag && bmax - bcount < bytes) || (n_flag && lmax - lcount < lines)) + if ((c_flag && bmax - bcount <= bytes) || (n_flag && lmax - lcount <= lines)) putchar(buf[i]); else if (!_TAIL_C) { @@ -92,6 +83,10 @@ static int print(const char *file, FILE *fp, long lines, long bytes) { if ((n_flag && lcount == lmax + lines) || (c_flag && bcount == bmax + bytes)) break; } + + if (buf[i] == '\n') + lcount++; + bcount++; } free(buf); diff --git a/src/kill.c b/src/kill.c index 8a0656f..2312d54 100644 --- a/src/kill.c +++ b/src/kill.c @@ -30,10 +30,10 @@ static SIG signals[] = { {"ALRM", SIGALRM}, {"TERM", SIGTERM}, {"CHLD", SIGCHLD}, - {"STOP", SIGSTOP} + {"STOP", SIGSTOP}, + {"WINCH", SIGWINCH} }; - static int parse_sig(char *arg) { int sig = atoi(arg); if (sig > 0 && sig <= NSIG) diff --git a/src/ls.c b/src/ls.c index d9a84fe..826e836 100644 --- a/src/ls.c +++ b/src/ls.c @@ -24,7 +24,6 @@ static char O_flag; static char a_flag; static char l_flag; static char F_flag; -static char c_flag; static char R_flag; static char d_flag; static char L_flag; @@ -145,7 +144,6 @@ static char *get_date(const time_t mtime) { /* Print */ static int print(const struct d_node *node) { char suf = ' '; - char *color = ""; char *mode = mu_mode_2_str(node->stats.st_mode); if (S_ISDIR(node->stats.st_mode)) { @@ -153,36 +151,28 @@ static int print(const struct d_node *node) { suf = '/'; mode[0] = 'd'; - color = LS_DIR_COLOR; } else if (S_ISLNK(node->stats.st_mode)) { suf = '@'; mode[0] = 'l'; - color = LS_LINK_COLOR; } else if (S_ISSOCK(node->stats.st_mode)) { suf = '='; mode[0] = 's'; - color = LS_SOCK_COLOR; } - else if (S_ISBLK(node->stats.st_mode)) { + else if (S_ISBLK(node->stats.st_mode)) mode[0] = 'b'; - color = LS_BLOCK_COLOR; - } else if (S_ISFIFO(node->stats.st_mode)) { suf = '|'; mode[0] = 'p'; - color = LS_FIFO_COLOR; } - else if ((node->stats.st_mode & S_IXUSR) || (node->stats.st_mode & S_IXGRP) || (node->stats.st_mode & S_IXOTH)) { + else if ((node->stats.st_mode & S_IXUSR) || (node->stats.st_mode & S_IXGRP) || (node->stats.st_mode & S_IXOTH)) suf = '*'; - color = LS_EXE_COLOR; - } int ret = 0; if (i_flag) @@ -214,15 +204,9 @@ static int print(const struct d_node *node) { ret += printf(" %4ju %4s %6s %10ld %s ", (uintmax_t)node->stats.st_nlink, pw->pw_name, gr->gr_name, node->stats.st_size, get_date(node->stats.st_mtime)); } - if (c_flag && p_flag) - printf("%s", color); - printf("%s", node->name); ret += mu_strlen(node->name); - if (c_flag && p_flag) - printf("\033[0m"); - if (F_flag) printf("%c", suf); @@ -410,7 +394,7 @@ static int ls_files(int argc, char **argv, const struct winsize w) { int main(int argc, char **argv) { int opt; - while ((opt = getopt(argc, argv, "1alFcRdLhistS0")) != -1) { + while ((opt = getopt(argc, argv, "1alFRdLhistS0")) != -1) { switch (opt) { case '1': O_flag = 1; @@ -428,10 +412,6 @@ int main(int argc, char **argv) { F_flag = 1; break; - case 'c': - c_flag = 1; - break; - case 'R': d_flag = 0; R_flag = 1; @@ -471,7 +451,7 @@ int main(int argc, char **argv) { break; default: - puts("ls [1alFcRdLhistS0] [dir1 file2...]\n\t-a Show hidden files\n\t-l Use a long listing format\n\t-F Append indicator to names\n\t-c Color mode\n\t-R Recursive\n\t-1 One column\n\t-d Print only dir names\n\t-L Follow symlinks\n\t-h Sizes in human readable format\n\t-i Listen inodes\n\t-t Sort by mtime\n\t-S Sort by size\n\t-s Print file size\n\t-0 End line with \\0"); + puts("ls [1alFcRdLhistS0] [dir1 file2...]\n\t-a Show hidden files\n\t-l Use a long listing format\n\t-F Append indicator to names\n\t-R Recursive\n\t-1 One column\n\t-d Print only dir names\n\t-L Follow symlinks\n\t-h Sizes in human readable format\n\t-i Listen inodes\n\t-t Sort by mtime\n\t-S Sort by size\n\t-s Print file size\n\t-0 End line with \\0"); return 0; } } diff --git a/src/que.c b/src/que.c deleted file mode 100644 index 9f87a16..0000000 --- a/src/que.c +++ /dev/null @@ -1,619 +0,0 @@ -/* Safe variant of kilo editor */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#define CTRL_KEY(k) ((k) & 0x1f) -#define TAB_SIZE 8 - -static struct termios orig_termios; -static struct winsize ws; - -static char *scr_buf; -static size_t scr_buf_size; - -struct row { - char *buf; - size_t len; - - char *render; - size_t rlen; -}; - -static struct row *row_s; -static size_t row_size; - -/* Cursors */ -static unsigned int curx; -static unsigned int cury; -static unsigned int renx; - -static unsigned int rowoff; -static unsigned int coloff; - -static char *file_path; - -enum { - FAILED_SAVE = 1, - SUCCESS_SAVE -}; -static char status_type; -static char modified_flag; - -/* Cleaners */ -static void bufFree(void) { - if (scr_buf != NULL) - free(scr_buf); - - scr_buf = NULL; - scr_buf_size = 0; -} - -static void fileBufFree(void) { - if (row_s != NULL) { - if (row_size > 0) - for (size_t i = 0; i < row_size; i++) { - if (row_s[i].buf) - free(row_s[i].buf); - - if (row_s[i].render) - free(row_s[i].render); - } - - free(row_s); - } - - row_s = NULL; - row_size = 0; -} - -static void die(int ret, char *msg) { - write(STDOUT_FILENO, "\033[H\033[J", 6); - - bufFree(); - fileBufFree(); - - if (msg != NULL) - fprintf(stderr, "que: %s: %s\n", msg, strerror(errno)); - - exit(ret); -} - -/* Save */ -static char *buf2str(size_t *len) { - size_t totalen = 0; - for (size_t i = 0; i < row_size; i++) - totalen += row_s[i].len + 1; - - *len = totalen; - char *buf = malloc(totalen + 1); - if (buf == NULL) - die(1, "malloc in buf2str: Fatal error"); - - char *p = buf; - for (size_t i = 0; i < row_size; i++) { - memcpy(p, row_s[i].buf, row_s[i].len); - - p += row_s[i].len; - *p = '\n'; - p++; - } - - *p = '\0'; - return buf; -} - -static void save(void) { - size_t len = 0; - char *buf = buf2str(&len); - - int fd = open(file_path, O_RDWR, 0644); - if (fd < 0) - goto BAD_SAVE; - - if (ftruncate(fd, len) < 0) - goto BAD_SAVE; - - ssize_t ret = write(fd, buf, len); - if (ret == -1) - goto BAD_SAVE; - - else if ((size_t)ret != len) - goto BAD_SAVE; - - close(fd); - free(buf); - status_type = SUCCESS_SAVE; - modified_flag = 0; - return; - -BAD_SAVE: - free(buf); - status_type = FAILED_SAVE; - return; -} - -/* Funcs */ -static void bufAppend(const char *str, const size_t len) { - if (len == 0) - return; - - char *buf = NULL; - if (scr_buf_size == 0 || scr_buf == NULL) - buf = malloc(len); - - else - buf = realloc(scr_buf, scr_buf_size + len); - - if (buf == NULL) { - if (scr_buf) - free(scr_buf); - - scr_buf_size = 0; - return; - } - - scr_buf = buf; - - memcpy(&scr_buf[scr_buf_size], str, len); - scr_buf_size += len; -} - -static int updateRenderStr(const unsigned int row) { - int tabs = 0; - for (size_t i = 0; i < row_s[row].len; i++) - if (row_s[row].buf[i] == '\t') - tabs++; - - if (row_s[row].render) - free(row_s[row].render); - - char *buf = malloc(row_s[row].len + tabs * TAB_SIZE + 1); - if (buf == NULL) - return 1; - row_s[row].render = buf; - - int j = 0; - for (size_t i = 0; i < row_s[row].len; i++) { - if (row_s[row].buf[i] == '\t') { - row_s[row].render[j++] = ' '; - while (j % TAB_SIZE != 0) - row_s[row].render[j++] = ' '; - } - - else - row_s[row].render[j++] = row_s[row].buf[i]; - } - - row_s[row].render[j] = '\0'; - row_s[row].rlen = j; - - return 0; -} - -static int addRow(const unsigned int at, const char *buf, const size_t len) { - struct row *row_s2 = realloc(row_s, sizeof(struct row) * (row_size + 1)); - if (row_s2 == NULL) - return 1; - row_s = row_s2; - - memmove(&row_s[at + 1], &row_s[at], sizeof(struct row) * (row_size - at)); - - char *buf2 = malloc(len + 1); - if (buf2 == NULL) - return 1; - row_s[at].buf = buf2; - - memcpy(row_s[at].buf, buf, len); - row_s[at].len = len; - row_s[at].buf[len] = '\0'; - - row_s[at].render = NULL; - if (updateRenderStr(at)) - return 1; - - row_size++; - return 0; -} - -static void readFile(const char *path) { - row_s = malloc(sizeof(struct row)); - if (row_s == NULL) - die(1, "malloc in readFIle"); - - FILE *fp = fopen(path, "r"); - if (fp == NULL) - die(1, "fopen in readFile"); - - char *buf = NULL; - size_t n = 0; - ssize_t len = 0; - while ((len = getline(&buf, &n, fp)) != -1) { - while (len > 0 && (buf[len - 1] == '\n' || buf[len - 1] == '\r')) - len--; - - if (addRow(row_size, buf, len)) { - fclose(fp); - free(buf); - die(1, "addRow in readFile"); - } - } - - if (buf) - free(buf); - - fclose(fp); -} - -static void insertChar(char c) { - if ((size_t)cury == row_size) { - if (addRow(row_size, "", 0)) { - save(); - die(1, "addRow in insertChar: Fatal error"); - } - } - - size_t i = (size_t)curx; - if (i > row_s[cury].len) - i = row_s[cury].len; - - char *buf = realloc(row_s[cury].buf, row_s[cury].len + 2); - if (buf == NULL) { - save(); - die(1, "realloc in insertChar: Fatal error"); - } - row_s[cury].buf = buf; - - memmove(&row_s[cury].buf[i + 1], &row_s[cury].buf[i], row_s[cury].len - i + 1); - - row_s[cury].len++; - row_s[cury].buf[i] = c; - if (updateRenderStr(cury)) { - save(); - die(1, "updateRenderStr in insertChar: Fatal error"); - } - - curx++; -} - -static void insertNewline(void) { - if (curx == 0) { - if (addRow(cury, "", 0)) { - save(); - die(1, "addRow in insertNewline: Fatal error"); - } - } - - else { - if (addRow(cury + 1, &row_s[cury].buf[curx], row_s[cury].len - curx)) { - save(); - die(1, "addRow in insertNewline: Fatal error"); - } - - /* Resize */ - row_s[cury].len = (size_t)curx; - row_s[cury].buf[curx] = '\0'; - - char *buf = strdup(row_s[cury].buf); - if (buf == NULL) { - save(); - die(1, "strdup in insertNewline: Fatal error"); - } - - free(row_s[cury].buf); - row_s[cury].buf = buf; - - if (updateRenderStr(cury)) { - save(); - die(1, "updateRenderStr in insertNewline: Fatal error"); - } - } - - cury++; - curx = 0; -} - -static void delChar(void) { - if ((curx == 0 && cury == 0) || cury == (unsigned int)row_size) - return; - - else if (curx > 0) { - if (curx - 1 >= (unsigned int)row_s[cury].len) - return; - - memmove(&row_s[cury].buf[curx - 1], &row_s[cury].buf[curx], row_s[cury].len - curx); - - row_s[cury].len--; - curx--; - } - - else { - curx = (unsigned int)row_s[cury - 1].len; - - char *buf = realloc(row_s[cury - 1].buf, row_s[cury - 1].len + row_s[cury].len + 1); - if (buf == NULL) { - save(); - die(1, "realloc in delChar: Fatal error"); - } - row_s[cury - 1].buf = buf; - - memcpy(&row_s[cury - 1].buf[row_s[cury - 1].len], row_s[cury].buf, row_s[cury].len); - row_s[cury - 1].len += row_s[cury].len; - row_s[cury - 1].buf[row_s[cury - 1].len] = '\0'; - - if (cury < (unsigned int)row_size) { - free(row_s[cury].buf); - free(row_s[cury].render); - - memmove(&row_s[cury], &row_s[cury + 1], sizeof(struct row) * (row_size - cury - 1)); - struct row *buf2 = realloc(row_s, sizeof(struct row) * row_size - 1); - if (buf == NULL) { - save(); - die(1, "relloc in delChar: Fatal error"); - } - - row_s = buf2; - row_size--; - } - - cury--; - } - - if (updateRenderStr(cury)) { - save(); - die(1, "updateRenderStr in delChar: Fatal error"); - } -} - -/* Terminal */ -static void DRawMode(void) { - if (tcsetattr(STDIN_FILENO, TCSAFLUSH, &orig_termios) < 0) - die(1, "tcsetattr"); -} - -static void ERawMode(void) { - if (tcgetattr(STDIN_FILENO, &orig_termios) < 0) - die(1, "tcgetattr"); - - struct termios raw = orig_termios; - raw.c_oflag &= ~(OPOST); - raw.c_cflag |= (CS8); - raw.c_iflag &= ~(BRKINT | ICRNL | INPCK | ISTRIP | IXON); - raw.c_lflag &= ~(ECHO | ICANON | ISIG | IEXTEN); - - raw.c_cc[VMIN] = 0; - raw.c_cc[VTIME] = 1; - - if (tcsetattr(STDIN_FILENO, TCSAFLUSH, &raw) < 0) - die(1, "tcsetattr"); -} - -static void winsize(void) { - if (ioctl(STDOUT_FILENO, TIOCGWINSZ, &ws) < 0) - die(1, "ioctl"); - - if (ws.ws_col == 0 || ws.ws_row <= 1) - die(1, "winsize"); - - ws.ws_row--; -} - -static void statusBar(const char *path) { - char info[124]; - int ret = 0; - - if (status_type == 0) - ret = snprintf(info, sizeof(info), "LINE: %u/%zu %s [%s]", cury + 1, row_size + 1, (modified_flag) ? "[modified]" : "", path); - - else if (status_type == FAILED_SAVE) - ret = snprintf(info, sizeof(info), "Failed save to %s: %s", path, strerror(errno)); - - else if (status_type == SUCCESS_SAVE) - ret = snprintf(info, sizeof(info), "File %s success saved", path); - - status_type = 0; - bufAppend(info, ret); -} - -/* Keyboard */ -static char readkey(void) { - char c; - int ret; - - while ((ret = read(STDIN_FILENO, &c, 1)) != 1) { - if (ret < 0 && errno != EAGAIN) { - save(); - die(1, "read"); - } - } - - return c; -} - -static void moveCursor(char c) { - switch (c) { - case 'A': - if (cury != 0) - cury--; - - break; - - case 'B': - if (cury < row_size) - cury++; - - break; - - case 'C': - if (curx < row_s[cury].len) - curx++; - - else if (curx == row_s[cury].len) { - cury++; - curx = 0; - } - - break; - - case 'D': - if (curx != 0) - curx--; - - - else if (cury > 0) { - cury--; - curx = row_s[cury].len; - } - - break; - - case '5': - if (readkey() == '~') { - cury = rowoff; - - size_t t = ws.ws_row; - while (t--) - if (cury != 0) - moveCursor('A'); - } - - break; - - case '6': - if (readkey() == '~') { - cury = rowoff + ws.ws_row + 1; - - if (cury > (unsigned int)row_size) - cury = row_size; - - size_t t = ws.ws_row; - while (t--) - moveCursor('B'); - } - - break; - - case 'H': - curx = 0; - break; - - case 'F': - curx = row_s[cury].len; - break; - } - - if (curx > row_s[cury].len) - curx = row_s[cury].len; -} - -static void keyboard(void) { - char key = readkey(); - switch (key) { - case '\033': - if (readkey() != '[') - break; - - moveCursor(readkey()); - break; - - case '\r': - modified_flag = 1; - insertNewline(); - break; - - case CTRL_KEY('q'): - die(0, NULL); - break; - - case CTRL_KEY('s'): - save(); - break; - - case 127: - case CTRL_KEY('h'): - delChar(); - modified_flag = 1; - break; - - default: - modified_flag = 1; - insertChar(key); - break; - } -} - -int main(int argc, char **argv) { - if (argc < 2) { - printf("que [file]\n"); - return 0; - } - - file_path = argv[1]; - readFile(file_path); - winsize(); - atexit(DRawMode); - ERawMode(); - - while (1) { - bufAppend("\033[H\033[J", 6); - - renx = 0; - - if (cury < row_size) { - /* Buffer coord to Render buffer coord */ - for (unsigned int i = 0; i < curx; i++) { - if (row_s[cury].buf[i] == '\t') - renx += (TAB_SIZE - 1) - (renx % TAB_SIZE); - - renx++; - } - } - - if (cury < rowoff) - rowoff = cury; - - else if (cury >= rowoff + ws.ws_row) - rowoff = cury - ws.ws_row + 1; - - if (renx < coloff) - coloff = renx; - - else if (renx >= coloff + ws.ws_col) - coloff = renx - ws.ws_col + 1; - - for (size_t i = 0; i < ws.ws_row; i++) { - unsigned int row = rowoff + i; - - if (row_size > row) { - int len = row_s[row].rlen - coloff; - if (len < 0) - len = 0; - - else if (len > ws.ws_col) - len = ws.ws_col; - - bufAppend(&row_s[row].render[coloff], (size_t)len); - } - - bufAppend("\r\n", 2); - } - - statusBar(file_path); - - char buf[32]; - int ret = snprintf(buf, sizeof(buf), "\033[%u;%uH", cury - rowoff + 1, renx - coloff + 1); - bufAppend(buf, ret); - - write(STDOUT_FILENO, scr_buf, scr_buf_size); - bufFree(); - - keyboard(); - } -} diff --git a/src/tail.c b/src/tail.c index 7d0d04e..9d7f636 100644 --- a/src/tail.c +++ b/src/tail.c @@ -1,2 +1,6 @@ +#ifdef _BOX +#define head_main tail_main +#endif + #define _TAIL_C 1 #include "head.c" diff --git a/src/touch.c b/src/touch.c index e5539a7..c3542d0 100644 --- a/src/touch.c +++ b/src/touch.c @@ -34,7 +34,7 @@ static int touch(const char *path, const time_t date) { if (!c_flag) { int fd = open(path, O_CREAT | O_RDONLY, 0666); if (fd < 0) { - fprintf(stderr, "touch: %s\n", strerror(errno)); + fprintf(stderr, "touch: %s: %s\n", path, strerror(errno)); return 1; }