fixed
This commit is contained in:
parent
ea0004c11f
commit
2980f205df
@ -5,8 +5,9 @@ License: wtfpl
|
|||||||
https://trivial.technology/
|
https://trivial.technology/
|
||||||
|
|
||||||
Unportable:
|
Unportable:
|
||||||
proc_parser
|
proc_parser.h
|
||||||
ps
|
ps
|
||||||
|
kill
|
||||||
dmesg
|
dmesg
|
||||||
mount
|
mount
|
||||||
umount
|
umount
|
||||||
|
24
TODO
24
TODO
@ -1,55 +1,33 @@
|
|||||||
With "micro-" prefix
|
|
||||||
|
|
||||||
*Todo:
|
*Todo:
|
||||||
tail
|
|
||||||
expr
|
expr
|
||||||
uniq
|
uniq
|
||||||
od
|
|
||||||
tr
|
tr
|
||||||
cut
|
cut
|
||||||
shuf
|
|
||||||
stty
|
stty
|
||||||
sort
|
sort
|
||||||
test
|
test
|
||||||
tar
|
tar
|
||||||
sha*
|
sha*
|
||||||
md5
|
md5
|
||||||
|
|
||||||
Other:
|
|
||||||
sysctl
|
sysctl
|
||||||
ping
|
ping
|
||||||
ncat
|
ncat
|
||||||
ntpd
|
ntpd
|
||||||
ifconfig
|
ifconfig
|
||||||
|
ipconfig
|
||||||
dhcp-client
|
dhcp-client
|
||||||
getopt
|
getopt
|
||||||
fdisk
|
fdisk
|
||||||
less
|
less
|
||||||
free
|
free
|
||||||
swapon
|
|
||||||
swapoff
|
|
||||||
hexdump
|
|
||||||
sed
|
sed
|
||||||
|
|
||||||
Loginutils:
|
|
||||||
usersctl
|
usersctl
|
||||||
getty
|
getty
|
||||||
|
|
||||||
Modutils:
|
|
||||||
insmod
|
insmod
|
||||||
rmmod
|
rmmod
|
||||||
lsmod
|
lsmod
|
||||||
|
|
||||||
Findutils:
|
|
||||||
grep
|
grep
|
||||||
find
|
find
|
||||||
|
|
||||||
BUGS:
|
|
||||||
ls (-l flag with long group/user name)
|
|
||||||
xargs (getopt with glibc)
|
|
||||||
|
|
||||||
FIX:
|
FIX:
|
||||||
xargs (-d)
|
|
||||||
echo (escape)
|
echo (escape)
|
||||||
que (unicode)
|
|
||||||
ps (-o)
|
|
||||||
|
4
build.sh
4
build.sh
@ -1,5 +1,4 @@
|
|||||||
#!/bin/sh
|
#!/bin/sh
|
||||||
./clean.sh
|
|
||||||
|
|
||||||
if [ -z $CC ]; then
|
if [ -z $CC ]; then
|
||||||
CC="cc"
|
CC="cc"
|
||||||
@ -9,7 +8,8 @@ if [ -z $CFLAGS ]; then
|
|||||||
CFLAGS="-s -Os -Wextra -Wall -pedantic"
|
CFLAGS="-s -Os -Wextra -Wall -pedantic"
|
||||||
fi
|
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
|
./libmu/build-libmu.sh
|
||||||
|
|
||||||
if [[ $1 == "box" ]]; then
|
if [[ $1 == "box" ]]; then
|
||||||
|
@ -26,23 +26,6 @@
|
|||||||
#define MOUNT_OPT_SIZE 512
|
#define MOUNT_OPT_SIZE 512
|
||||||
#endif
|
#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
|
#ifdef _UNAME_C
|
||||||
/* Os name for uname */
|
/* Os name for uname */
|
||||||
/* #define OS_NAME "unknow" */
|
/* #define OS_NAME "unknow" */
|
||||||
|
@ -50,5 +50,5 @@ int main(int argc, char **argv) {
|
|||||||
}
|
}
|
||||||
EOF
|
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
|
echo $CFLAGS | xargs $CC -Iconfigs scripts/musuid.c -o musuid
|
||||||
|
@ -32,7 +32,7 @@ int main(int argc, char **argv) {
|
|||||||
break;
|
break;
|
||||||
|
|
||||||
default:
|
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;
|
return 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
13
src/cat.c
13
src/cat.c
@ -31,21 +31,12 @@ static int cat(const char *path) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
int main(int argc, char **argv) {
|
int main(int argc, char **argv) {
|
||||||
int opt;
|
if (argc == 1)
|
||||||
while ((opt = getopt(argc, argv, "")) != -1) {
|
|
||||||
puts("cat [file1 file2...]");
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
argv += optind;
|
|
||||||
argc -= optind;
|
|
||||||
|
|
||||||
if (argc == 0)
|
|
||||||
return cat("-");
|
return cat("-");
|
||||||
|
|
||||||
else {
|
else {
|
||||||
int ret = 0;
|
int ret = 0;
|
||||||
for (int i = 0; i < argc; i++)
|
for (int i = 1; i < argc; i++)
|
||||||
if (cat(argv[i]))
|
if (cat(argv[i]))
|
||||||
ret = 1;
|
ret = 1;
|
||||||
|
|
||||||
|
93
src/chgrp.c
93
src/chgrp.c
@ -1,93 +0,0 @@
|
|||||||
#include <grp.h>
|
|
||||||
#include <stdio.h>
|
|
||||||
#include <stdlib.h>
|
|
||||||
#include <string.h>
|
|
||||||
#include <unistd.h>
|
|
||||||
#include <dirent.h>
|
|
||||||
#include <errno.h>
|
|
||||||
#include <sys/stat.h>
|
|
||||||
#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;
|
|
||||||
}
|
|
64
src/chown.c
64
src/chown.c
@ -12,18 +12,26 @@
|
|||||||
#include "unused.h"
|
#include "unused.h"
|
||||||
|
|
||||||
static char r_flag;
|
static char r_flag;
|
||||||
static char *f_flag = "chown";
|
static char *s_flag = "chown";
|
||||||
static char H_flag;
|
static char H_flag;
|
||||||
static char v_flag;
|
static char v_flag;
|
||||||
|
static char g_flag;
|
||||||
static int (*chown_func)(const char *pathname, uid_t owner, gid_t group);
|
static int (*chown_func)(const char *pathname, uid_t owner, gid_t group);
|
||||||
static long gid;
|
static long gid = -1;
|
||||||
static long uid;
|
static long uid = -1;
|
||||||
|
|
||||||
static int change(const char *path, void *p) {
|
static int change(const char *path, void *p) {
|
||||||
char *name = (char *)p;
|
char *name = (char *)p;
|
||||||
|
|
||||||
if (chown_func(path, uid, gid)) {
|
struct stat sb;
|
||||||
if (f_flag)
|
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));
|
fprintf(stderr, "chown: unable to chown %s: %s\n", path, strerror(errno));
|
||||||
|
|
||||||
return 1;
|
return 1;
|
||||||
@ -35,25 +43,31 @@ static int change(const char *path, void *p) {
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void get_owner(const char *arg) {
|
static void get_owner(char *arg) {
|
||||||
char *group = strchr(arg, ':');
|
char *group = strchr(arg, ':');
|
||||||
|
char gg_flag = 1;
|
||||||
|
char gu_flag = 1;
|
||||||
|
|
||||||
char g_flag = 1;
|
if (group == NULL) {
|
||||||
char u_flag = 1;
|
if (g_flag)
|
||||||
|
gu_flag = 0;
|
||||||
|
|
||||||
if (group == arg)
|
else
|
||||||
u_flag = 0;
|
gg_flag = 0;
|
||||||
|
}
|
||||||
|
|
||||||
else if (!group)
|
if (gg_flag) {
|
||||||
g_flag = 0;
|
if (g_flag == 0) {
|
||||||
|
|
||||||
if (g_flag) {
|
|
||||||
group[0] = '\0';
|
group[0] = '\0';
|
||||||
group++;
|
group++;
|
||||||
|
}
|
||||||
|
|
||||||
|
else
|
||||||
|
group = arg;
|
||||||
|
|
||||||
struct group *grp = getgrnam(group);
|
struct group *grp = getgrnam(group);
|
||||||
if (!grp) {
|
if (!grp) {
|
||||||
if (f_flag)
|
if (s_flag)
|
||||||
fprintf(stderr, "chown: invalid group: %s\n", group);
|
fprintf(stderr, "chown: invalid group: %s\n", group);
|
||||||
|
|
||||||
exit(1);
|
exit(1);
|
||||||
@ -62,10 +76,10 @@ static void get_owner(const char *arg) {
|
|||||||
gid = grp->gr_gid;
|
gid = grp->gr_gid;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (u_flag) {
|
if (gu_flag) {
|
||||||
struct passwd *pwd = getpwnam(arg);
|
struct passwd *pwd = getpwnam(arg);
|
||||||
if (!pwd) {
|
if (!pwd) {
|
||||||
if (f_flag)
|
if (s_flag)
|
||||||
fprintf(stderr, "chown: invalid user: %s\n", arg);
|
fprintf(stderr, "chown: invalid user: %s\n", arg);
|
||||||
|
|
||||||
exit(1);
|
exit(1);
|
||||||
@ -79,14 +93,14 @@ int main(int argc, char **argv) {
|
|||||||
chown_func = lchown;
|
chown_func = lchown;
|
||||||
|
|
||||||
int opt;
|
int opt;
|
||||||
while ((opt = getopt(argc, argv, "RfHv")) != -1) {
|
while ((opt = getopt(argc, argv, "RsHvg")) != -1) {
|
||||||
switch (opt) {
|
switch (opt) {
|
||||||
case 'R':
|
case 'R':
|
||||||
r_flag = 1;
|
r_flag = 1;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 'f':
|
case 's':
|
||||||
f_flag = NULL;
|
s_flag = NULL;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 'H':
|
case 'H':
|
||||||
@ -98,8 +112,12 @@ int main(int argc, char **argv) {
|
|||||||
v_flag = 1;
|
v_flag = 1;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case 'g':
|
||||||
|
g_flag = 1;
|
||||||
|
break;
|
||||||
|
|
||||||
default:
|
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;
|
return 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -112,14 +130,12 @@ int main(int argc, char **argv) {
|
|||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
gid = -1;
|
|
||||||
uid = -1;
|
|
||||||
get_owner(argv[0]);
|
get_owner(argv[0]);
|
||||||
|
|
||||||
int ret = 0;
|
int ret = 0;
|
||||||
for (int i = 1; i < argc; i++) {
|
for (int i = 1; i < argc; i++) {
|
||||||
if (r_flag) {
|
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;
|
ret = 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -60,8 +60,6 @@ int main(int argc, char **argv) {
|
|||||||
if (write(STDOUT_FILENO, buf, n) != n)
|
if (write(STDOUT_FILENO, buf, n) != n)
|
||||||
fprintf(stderr, "dmesg: %s\n", strerror(errno));
|
fprintf(stderr, "dmesg: %s\n", strerror(errno));
|
||||||
|
|
||||||
putchar('\n');
|
|
||||||
|
|
||||||
free(buf);
|
free(buf);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
12
src/du.c
12
src/du.c
@ -12,6 +12,7 @@
|
|||||||
static char h_flag;
|
static char h_flag;
|
||||||
static char s_flag;
|
static char s_flag;
|
||||||
static char c_flag;
|
static char c_flag;
|
||||||
|
static char a_flag;
|
||||||
static off_t total;
|
static off_t total;
|
||||||
|
|
||||||
static void print(off_t size, const char *filename) {
|
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)
|
else if (!recurs_flag)
|
||||||
print(sum, path);
|
print(sum, path);
|
||||||
|
|
||||||
|
else if (a_flag && !s_flag)
|
||||||
|
print(sb.st_blocks, path);
|
||||||
|
|
||||||
return sum;
|
return sum;
|
||||||
}
|
}
|
||||||
|
|
||||||
int main(int argc, char **argv) {
|
int main(int argc, char **argv) {
|
||||||
|
|
||||||
int opt;
|
int opt;
|
||||||
while ((opt = getopt(argc, argv, "hsc")) != -1) {
|
while ((opt = getopt(argc, argv, "hsca")) != -1) {
|
||||||
switch (opt) {
|
switch (opt) {
|
||||||
case 'h':
|
case 'h':
|
||||||
h_flag = 1;
|
h_flag = 1;
|
||||||
@ -87,8 +91,12 @@ int main(int argc, char **argv) {
|
|||||||
c_flag = 1;
|
c_flag = 1;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case 'a':
|
||||||
|
a_flag = 1;
|
||||||
|
break;
|
||||||
|
|
||||||
default:
|
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;
|
return 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
19
src/head.c
19
src/head.c
@ -45,7 +45,6 @@ static int print(const char *file, FILE *fp, long lines, long bytes) {
|
|||||||
long lmax = 0;
|
long lmax = 0;
|
||||||
long bmax = 0;
|
long bmax = 0;
|
||||||
|
|
||||||
/* Make buffer */
|
|
||||||
size_t buf_size = 0;
|
size_t buf_size = 0;
|
||||||
char *buf = malloc(1);
|
char *buf = malloc(1);
|
||||||
if (buf == NULL) {
|
if (buf == NULL) {
|
||||||
@ -54,11 +53,8 @@ static int print(const char *file, FILE *fp, long lines, long bytes) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* Fill buffer */
|
/* Fill buffer */
|
||||||
while (1) {
|
int c = 0;
|
||||||
int c = getc(fp);
|
while ((c = getc(fp)) != EOF) {
|
||||||
if (c == EOF)
|
|
||||||
break;
|
|
||||||
|
|
||||||
char *tmp = realloc(buf, buf_size + 2);
|
char *tmp = realloc(buf, buf_size + 2);
|
||||||
if (tmp == NULL) {
|
if (tmp == NULL) {
|
||||||
fprintf(stderr, "%s: realloc: %s\n", PROG_NAME, strerror(errno));
|
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 */
|
/* Print buffer */
|
||||||
for (size_t i = 0; i < buf_size; i++) {
|
for (size_t i = 0; i < buf_size; i++) {
|
||||||
if (buf[i] == '\n')
|
if ((c_flag && bmax - bcount <= bytes) || (n_flag && lmax - lcount <= lines))
|
||||||
lcount++;
|
|
||||||
|
|
||||||
bcount++;
|
|
||||||
|
|
||||||
if ((c_flag && bmax - bcount < bytes) || (n_flag && lmax - lcount < lines))
|
|
||||||
putchar(buf[i]);
|
putchar(buf[i]);
|
||||||
|
|
||||||
else if (!_TAIL_C) {
|
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))
|
if ((n_flag && lcount == lmax + lines) || (c_flag && bcount == bmax + bytes))
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (buf[i] == '\n')
|
||||||
|
lcount++;
|
||||||
|
bcount++;
|
||||||
}
|
}
|
||||||
|
|
||||||
free(buf);
|
free(buf);
|
||||||
|
@ -30,10 +30,10 @@ static SIG signals[] = {
|
|||||||
{"ALRM", SIGALRM},
|
{"ALRM", SIGALRM},
|
||||||
{"TERM", SIGTERM},
|
{"TERM", SIGTERM},
|
||||||
{"CHLD", SIGCHLD},
|
{"CHLD", SIGCHLD},
|
||||||
{"STOP", SIGSTOP}
|
{"STOP", SIGSTOP},
|
||||||
|
{"WINCH", SIGWINCH}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
static int parse_sig(char *arg) {
|
static int parse_sig(char *arg) {
|
||||||
int sig = atoi(arg);
|
int sig = atoi(arg);
|
||||||
if (sig > 0 && sig <= NSIG)
|
if (sig > 0 && sig <= NSIG)
|
||||||
|
28
src/ls.c
28
src/ls.c
@ -24,7 +24,6 @@ static char O_flag;
|
|||||||
static char a_flag;
|
static char a_flag;
|
||||||
static char l_flag;
|
static char l_flag;
|
||||||
static char F_flag;
|
static char F_flag;
|
||||||
static char c_flag;
|
|
||||||
static char R_flag;
|
static char R_flag;
|
||||||
static char d_flag;
|
static char d_flag;
|
||||||
static char L_flag;
|
static char L_flag;
|
||||||
@ -145,7 +144,6 @@ static char *get_date(const time_t mtime) {
|
|||||||
/* Print */
|
/* Print */
|
||||||
static int print(const struct d_node *node) {
|
static int print(const struct d_node *node) {
|
||||||
char suf = ' ';
|
char suf = ' ';
|
||||||
char *color = "";
|
|
||||||
|
|
||||||
char *mode = mu_mode_2_str(node->stats.st_mode);
|
char *mode = mu_mode_2_str(node->stats.st_mode);
|
||||||
if (S_ISDIR(node->stats.st_mode)) {
|
if (S_ISDIR(node->stats.st_mode)) {
|
||||||
@ -153,36 +151,28 @@ static int print(const struct d_node *node) {
|
|||||||
suf = '/';
|
suf = '/';
|
||||||
|
|
||||||
mode[0] = 'd';
|
mode[0] = 'd';
|
||||||
color = LS_DIR_COLOR;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
else if (S_ISLNK(node->stats.st_mode)) {
|
else if (S_ISLNK(node->stats.st_mode)) {
|
||||||
suf = '@';
|
suf = '@';
|
||||||
mode[0] = 'l';
|
mode[0] = 'l';
|
||||||
color = LS_LINK_COLOR;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
else if (S_ISSOCK(node->stats.st_mode)) {
|
else if (S_ISSOCK(node->stats.st_mode)) {
|
||||||
suf = '=';
|
suf = '=';
|
||||||
mode[0] = 's';
|
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';
|
mode[0] = 'b';
|
||||||
color = LS_BLOCK_COLOR;
|
|
||||||
}
|
|
||||||
|
|
||||||
else if (S_ISFIFO(node->stats.st_mode)) {
|
else if (S_ISFIFO(node->stats.st_mode)) {
|
||||||
suf = '|';
|
suf = '|';
|
||||||
mode[0] = 'p';
|
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 = '*';
|
suf = '*';
|
||||||
color = LS_EXE_COLOR;
|
|
||||||
}
|
|
||||||
|
|
||||||
int ret = 0;
|
int ret = 0;
|
||||||
if (i_flag)
|
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));
|
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);
|
printf("%s", node->name);
|
||||||
ret += mu_strlen(node->name);
|
ret += mu_strlen(node->name);
|
||||||
|
|
||||||
if (c_flag && p_flag)
|
|
||||||
printf("\033[0m");
|
|
||||||
|
|
||||||
if (F_flag)
|
if (F_flag)
|
||||||
printf("%c", suf);
|
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 main(int argc, char **argv) {
|
||||||
int opt;
|
int opt;
|
||||||
while ((opt = getopt(argc, argv, "1alFcRdLhistS0")) != -1) {
|
while ((opt = getopt(argc, argv, "1alFRdLhistS0")) != -1) {
|
||||||
switch (opt) {
|
switch (opt) {
|
||||||
case '1':
|
case '1':
|
||||||
O_flag = 1;
|
O_flag = 1;
|
||||||
@ -428,10 +412,6 @@ int main(int argc, char **argv) {
|
|||||||
F_flag = 1;
|
F_flag = 1;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 'c':
|
|
||||||
c_flag = 1;
|
|
||||||
break;
|
|
||||||
|
|
||||||
case 'R':
|
case 'R':
|
||||||
d_flag = 0;
|
d_flag = 0;
|
||||||
R_flag = 1;
|
R_flag = 1;
|
||||||
@ -471,7 +451,7 @@ int main(int argc, char **argv) {
|
|||||||
break;
|
break;
|
||||||
|
|
||||||
default:
|
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;
|
return 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
619
src/que.c
619
src/que.c
@ -1,619 +0,0 @@
|
|||||||
/* Safe variant of kilo editor */
|
|
||||||
|
|
||||||
#include <fcntl.h>
|
|
||||||
#include <stdio.h>
|
|
||||||
#include <string.h>
|
|
||||||
#include <stdlib.h>
|
|
||||||
#include <unistd.h>
|
|
||||||
#include <sys/ioctl.h>
|
|
||||||
#include <termios.h>
|
|
||||||
#include <errno.h>
|
|
||||||
#include <ctype.h>
|
|
||||||
|
|
||||||
#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();
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,2 +1,6 @@
|
|||||||
|
#ifdef _BOX
|
||||||
|
#define head_main tail_main
|
||||||
|
#endif
|
||||||
|
|
||||||
#define _TAIL_C 1
|
#define _TAIL_C 1
|
||||||
#include "head.c"
|
#include "head.c"
|
||||||
|
@ -34,7 +34,7 @@ static int touch(const char *path, const time_t date) {
|
|||||||
if (!c_flag) {
|
if (!c_flag) {
|
||||||
int fd = open(path, O_CREAT | O_RDONLY, 0666);
|
int fd = open(path, O_CREAT | O_RDONLY, 0666);
|
||||||
if (fd < 0) {
|
if (fd < 0) {
|
||||||
fprintf(stderr, "touch: %s\n", strerror(errno));
|
fprintf(stderr, "touch: %s: %s\n", path, strerror(errno));
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user