first commit

This commit is contained in:
Your Name 2024-07-01 13:23:00 +03:00
commit 21be7fd279
156 changed files with 6939 additions and 0 deletions

View file

@ -0,0 +1,3 @@
#!/bin/sh
project_dir=$(pwd)
echo ./*.c $CFLAGS -o $OUTPUT$(basename $project_dir) | xargs $CC

View file

@ -0,0 +1,5 @@
#include <unistd.h>
int main(void) {
return write(1, "\033[H\033[J", 6) != 6;
}

View file

@ -0,0 +1,3 @@
#!/bin/sh
project_dir=$(pwd)
echo ./*.c $CFLAGS -o $OUTPUT$(basename $project_dir) | xargs $CC

View file

@ -0,0 +1,5 @@
#include <unistd.h>
int main(void) {
return write(1, "\033c\033(K\033[J\033[0m\033[?25h", 18) != 18;
}

View file

@ -0,0 +1,57 @@
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include <libgen.h>
char *bname(char *str, const char *suffix) {
char *base = basename(str);
if (suffix) {
char *ptr = base + strlen(base) - strlen(suffix);
if (!strcmp(ptr, suffix))
*ptr = '\0';
}
return base;
}
int main(int argc, char **argv) {
char *suffix = NULL;
char d_flag = 0;
int opt;
while ((opt = getopt(argc, argv, "s:d")) != -1) {
switch (opt) {
case 'd':
d_flag = 1;
break;
case 's':
suffix = optarg;
break;
default:
printf("bdname [sd] [str]\n\t-s SFX Set suffix\n\t-d Use dirname instead of basename\n");
return 0;
}
}
argv += optind;
argc -= optind;
if (argc == 0) {
fprintf(stderr, "bdname: missing operand\n");
return 1;
}
char *str = NULL;
if (d_flag)
str = dirname(argv[0]);
else
str = bname(argv[0], suffix);
puts(str);
return 0;
}

3
src/coreutils/bdname/build.sh Executable file
View file

@ -0,0 +1,3 @@
#!/bin/sh
project_dir=$(pwd)
echo ./*.c $CFLAGS -o $OUTPUT$(basename $project_dir) | xargs $CC

3
src/coreutils/cat/build.sh Executable file
View file

@ -0,0 +1,3 @@
#!/bin/sh
project_dir=$(pwd)
echo ./*.c $CFLAGS -o $OUTPUT$(basename $project_dir) | xargs $CC

54
src/coreutils/cat/cat.c Normal file
View file

@ -0,0 +1,54 @@
#include <fcntl.h>
#include <stdio.h>
#include <errno.h>
#include <string.h>
#include <unistd.h>
#include "config.h"
int cat(const char *path) {
int fd = STDIN_FILENO;
if (strcmp(path, "-"))
fd = open(path, O_RDONLY);
if (fd < 0) {
fprintf(stderr, "cat: %s: %s\n", path, strerror(errno));
return 1;
}
char buf[BUF_SIZE + 1];
off_t len = 0;
while ((len = read(fd, buf, sizeof(buf))) > 0)
if (write(STDOUT_FILENO, buf, len) != len) {
fprintf(stderr, "cat: %s\n", strerror(errno));
return 1;
}
if (strcmp(path, "-"))
close(fd);
return 0;
}
int main(int argc, char **argv) {
int opt;
while ((opt = getopt(argc, argv, "")) != -1) {
printf("cat [file1 file2...]\n");
return 0;
}
argv += optind;
argc -= optind;
if (argc == 0)
return cat("-");
else {
int ret = 0;
for (int i = 0; i < argc; i++)
if (cat(argv[i]))
ret = 1;
return ret;
}
}

3
src/coreutils/chgrp/build.sh Executable file
View file

@ -0,0 +1,3 @@
#!/bin/sh
project_dir=$(pwd)
echo ./*.c $CFLAGS -o $OUTPUT$(basename $project_dir) | xargs $CC

View file

@ -0,0 +1,92 @@
#include <grp.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <dirent.h>
#include <sys/stat.h>
#include "make_path.h"
#include "get_stat.h"
#include "recurse.h"
char r_flag;
char *f_flag = "chgrp";
char H_flag;
char v_flag;
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:
printf("chgrp [RfHv] [group] [file1 file2...]\n\t-H Symbolic link\n\t-R Recursive\n\t-f Silent\n\t-v Verbose\n");
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;
}

3
src/coreutils/chmod/build.sh Executable file
View file

@ -0,0 +1,3 @@
#!/bin/sh
project_dir=$(pwd)
echo ./*.c $CFLAGS -o $OUTPUT$(basename $project_dir) | xargs $CC

103
src/coreutils/chmod/chmod.c Normal file
View file

@ -0,0 +1,103 @@
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <dirent.h>
#include <sys/stat.h>
#include "mode_to_str.h"
#include "make_path.h"
#include "get_stat.h"
#include "parse_mode.h"
#include "recurse.h"
char r_flag;
char *f_flag = "chmod";
char H_flag;
char v_flag;
int change(const char *file, void *p) {
char *mode_arg = (char *)p;
struct stat sb;
if (mu_get_stats(f_flag, H_flag, file, &sb))
return 1;
mode_t mode = mu_parse_mode(mode_arg, sb.st_mode);
if (chmod(file, mode) != 0) {
if (f_flag)
fprintf(stderr, "chmod: unable to chown %s: %s\n", file, strerror(errno));
return 1;
}
if (v_flag)
printf("chmod: %s: changed mode to %s\n", file, mu_mode_2_str(mode));
return 0;
}
int main(int argc, char **argv) {
/* Arg hacking */
char *arg = NULL;
for (int i = 1; i < argc; i++) {
if (argv[i][0] != '-' || strlen(argv[i]) <= 1)
break;
else if (argv[i][1] == 'x' || argv[i][1] == 'r' || argv[i][1] == 'w') {
argv[i][0] = 'a';
arg = argv[i];
break;
}
}
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:
printf("chmod [RfHv] [ugoa]{+|-}[rwxXst] / [0 - 777] [file1 file2...]\n\t-H Symbolic link\n\t-R Recursive\n\t-f Silent\n\t-v Verbose\n");
return 0;
}
}
argv += optind;
argc -= optind;
if (argc == 0) {
fprintf(stderr, "chmod: missing operand\n");
return 0;
}
/* Restore arg */
if (arg)
arg[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))
ret = 1;
}
else
change(argv[i], argv[0]);
}
return ret;
}

3
src/coreutils/chown/build.sh Executable file
View file

@ -0,0 +1,3 @@
#!/bin/sh
project_dir=$(pwd)
echo ./*.c $CFLAGS -o $OUTPUT$(basename $project_dir) | xargs $CC

131
src/coreutils/chown/chown.c Normal file
View file

@ -0,0 +1,131 @@
#include <pwd.h>
#include <grp.h>
#include <stdio.h>
#include <errno.h>
#include <dirent.h>
#include <string.h>
#include <stdlib.h>
#include <unistd.h>
#include "make_path.h"
#include "get_stat.h"
#include "recurse.h"
#include "unused.h"
char r_flag;
char *f_flag = "chown";
char H_flag;
char v_flag;
int (*chown_func)(const char *pathname, uid_t owner, gid_t group);
long gid;
long uid;
int change(const char *path, void *p) {
char *name = (char *)p;
if (chown_func(path, uid, gid)) {
if (f_flag)
fprintf(stderr, "chown: unable to chown %s: %s\n", path, strerror(errno));
return 1;
}
if (v_flag)
printf("chown: %s: changed to %s\n", path, name);
return 0;
}
void get_owner(const char *arg) {
char *group = strchr(arg, ':');
char g_flag = 1;
char u_flag = 1;
if (group == arg)
u_flag = 0;
else if (!group)
g_flag = 0;
if (g_flag) {
group[0] = '\0';
group++;
struct group *grp = getgrnam(group);
if (!grp) {
if (f_flag)
fprintf(stderr, "chown: invalid group: %s\n", group);
exit(1);
}
gid = grp->gr_gid;
}
if (u_flag) {
struct passwd *pwd = getpwnam(arg);
if (!pwd) {
if (f_flag)
fprintf(stderr, "chown: invalid user: %s\n", arg);
exit(1);
}
uid = pwd->pw_gid;
}
}
int main(int argc, char **argv) {
chown_func = lchown;
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;
chown_func = chown;
break;
case 'v':
v_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");
return 0;
}
}
argv += optind;
argc -= optind;
if (argc == 0) {
fprintf(stderr, "chown: missing operand\n");
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))
ret = 1;
}
else
ret = change(argv[i], argv[0]);
}
return ret;
}

3
src/coreutils/chroot/build.sh Executable file
View file

@ -0,0 +1,3 @@
#!/bin/sh
project_dir=$(pwd)
echo ./*.c $CFLAGS -o $OUTPUT$(basename $project_dir) | xargs $CC

View file

@ -0,0 +1,29 @@
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include <errno.h>
int main(const int argc, char **argv) {
if (argc < 3 || !strcmp(argv[argc - 1], "--help")) {
printf("chroot [dir] [command] [arg arg2...]\n");
return 0;
}
if (chroot(argv[1]) < 0) {
fprintf(stderr, "chroot: %s\n", strerror(errno));
return 1;
}
if (chdir("/") < 0) {
fprintf(stderr, "chroot: %s\n", strerror(errno));
return 1;
}
if (execvp(argv[2], argv + 2) < 0) {
fprintf(stderr, "chroot: %s\n", strerror(errno));
return 1;
}
return 0;
}

3
src/coreutils/cmp/build.sh Executable file
View file

@ -0,0 +1,3 @@
#!/bin/sh
project_dir=$(pwd)
echo ./*.c $CFLAGS -o $OUTPUT$(basename $project_dir) | xargs $CC

126
src/coreutils/cmp/cmp.c Normal file
View file

@ -0,0 +1,126 @@
#include <stdio.h>
#include <errno.h>
#include <string.h>
#include <unistd.h>
#include <stdlib.h>
char s_flag;
int compare(FILE *fp1, FILE *fp2) {
if (fp1 == fp2)
return 0;
int ch1;
int ch2;
size_t byte = 1;
size_t lines = 1;
do {
ch1 = getc(fp1);
ch2 = getc(fp2);
if (ch1 != ch2) {
if (!s_flag)
printf("files differ at byte %zu and line %zu\n", byte, lines);
return 1;
}
if (ch1 == '\n')
lines++;
byte++;
} while(ch1 != EOF);
return 0;
}
long parse_int(const char *str) {
char *ptr;
long val = strtol(str, &ptr, 0);
if (*ptr || val < 0) {
fprintf(stderr, "cmp: invalid offset: %s\n", str);
exit(1);
}
return val;
}
FILE *file_open(const char *path) {
if (!strcmp(path, "-"))
return stdin;
FILE *fp = fopen(path, "r");
if (fp == NULL) {
fprintf(stderr, "cmp: %s\n", strerror(errno));
exit(1);
}
return fp;
}
int main(int argc, char **argv) {
int opt;
while ((opt = getopt(argc, argv, "s")) != -1) {
switch (opt) {
case 's':
s_flag = 1;
break;
default:
printf("cmp [s] [file1] [file2] [skip1] [skip2]\n\t-s Silent\n");
return 0;
}
}
argv += optind;
argc -= optind;
long skip1 = 0;
long skip2 = 0;
FILE *fp1 = NULL;
FILE *fp2 = stdin;
switch (argc) {
case 4:
skip2 = parse_int(argv[3]);
/* fallthrough */
case 3:
skip1 = parse_int(argv[2]);
/* fallthrough */
case 2:
fp2 = file_open(argv[1]);
/* fallthrough */
case 1:
fp1 = file_open(argv[0]);
break;
default:
fprintf(stderr, "cmp: missing operand\n");
return 1;
}
if (skip1 && fseek(fp1, skip1, SEEK_SET) < 0) {
if (!s_flag)
fprintf(stderr, "cmp: %s\n", strerror(errno));
return 1;
}
if (skip2 && fseek(fp2, skip2, SEEK_SET) < 0) {
if (!s_flag)
fprintf(stderr, "cmp: %s\n", strerror(errno));
return 1;
}
int ret = compare(fp1, fp2);
fclose(fp1);
fclose(fp2);
return ret;
}

3
src/coreutils/cp/build.sh Executable file
View file

@ -0,0 +1,3 @@
#!/bin/sh
project_dir=$(pwd)
echo ./*.c $CFLAGS -o $OUTPUT$(basename $project_dir) | xargs $CC

213
src/coreutils/cp/cp.c Normal file
View file

@ -0,0 +1,213 @@
#include <stdio.h>
#include <errno.h>
#include <fcntl.h>
#include <libgen.h>
#include <string.h>
#include <stdlib.h>
#include <unistd.h>
#include <dirent.h>
#include <limits.h>
#include <sys/mman.h>
#include "make_path.h"
#include "get_stat.h"
#include "config.h"
char *f_flag = "cp";
char r_flag;
char v_flag;
char L_flag;
char copy_reg(int mode, const char *src, const char *dst) {
int ret = 1;
int ifd = open(src, O_RDONLY);
if (ifd < 0)
return 1;
int ofd = open(dst, O_WRONLY | O_TRUNC | O_CREAT, mode);
if (ofd < 0)
goto CLOSE_OFD;
char buf[BUF_SIZE + 1];
while (1) {
ssize_t n = read(ifd, buf, sizeof(buf));
if (n <= 0) {
if (n < 0)
goto CLOSE;
break;
}
if (write(ofd, buf, n) != n)
goto CLOSE;
}
ret = 0;
CLOSE:
close(ofd);
CLOSE_OFD:
close(ifd);
return ret;
}
char copy_lnk(const char *src, const char *dst) {
char path[PATH_MAX + 1];
ssize_t ret = readlink(src, path, sizeof(path));
if (ret < 0)
return 1;
path[ret] = '\0';
if (symlink(path, dst) < 0)
return 1;
return 0;
}
char copy(struct stat st, const char *src, const char *dst) {
if (v_flag)
printf("Copying '%s' to '%s'\n", src, dst);
if (S_ISLNK(st.st_mode))
return copy_lnk(src, dst);
else if (S_ISCHR(st.st_mode) || S_ISBLK(st.st_mode) || S_ISFIFO(st.st_mode)) {
if (mknod(dst, st.st_mode, st.st_dev) < 0)
return 1;
}
else
return copy_reg(st.st_mode, src, dst);
return 0;
}
int cptree(const char *src, const char *dst) {
struct stat src_stat;
if (mu_get_stats(f_flag, !L_flag, src, &src_stat))
return 1;
if (!S_ISDIR(src_stat.st_mode)) {
if (copy(src_stat, src, dst)) {
if (f_flag)
fprintf(stderr, "cp: %s: %s\n", dst, strerror(errno));
return 1;
}
return 0;
}
else if (!r_flag) {
if (f_flag)
fprintf(stderr, "cp: omitting directory: %s\n", dst);
return 1;
}
else if (mkdir(dst, 0777) < 0) {
if (f_flag)
fprintf(stderr, "cp: %s: %s\n", dst, strerror(errno));
return 1;
}
DIR *dir = opendir(src);
if (dir == NULL) {
if (f_flag)
fprintf(stderr, "cp: %s: Can`t open directory\n", src);
return 1;
}
int ret = 0;
struct dirent *ep;
while ((ep = readdir(dir)) != NULL) {
if (!strcmp(ep->d_name, ".") || !strcmp(ep->d_name, "..") || !strcmp(dst, ep->d_name))
continue;
/* Copy */
char *src_path = mu_make_path(f_flag, src, ep->d_name);
if (src_path == NULL)
continue;
char *dst_path = mu_make_path(f_flag, dst, ep->d_name);
if (dst_path == NULL) {
free(src_path);
continue;
}
if (cptree(src_path, dst_path))
ret = 1;
free(src_path);
free(dst_path);
if (ret)
break;
}
closedir(dir);
return ret;
}
int main(int argc, char **argv) {
int opt;
while ((opt = getopt(argc, argv, "frvL")) != -1) {
switch (opt) {
case 'f':
f_flag = NULL;
break;
case 'r':
r_flag = 1;
break;
case 'v':
v_flag = 1;
break;
case 'L':
L_flag = 1;
break;
default:
printf("cp [frvL] [src1 src2...] [dst]\n\t-f Silent\n\t-r Recursive\n\t-v Verbose\n\t-L Follow all symlinks\n");
return 0;
}
}
argv += optind;
argc -= optind;
if (argc < 2) {
fprintf(stderr, "cp: missing operand\n");
return 1;
}
int ret = 0;
struct stat sb;
if (!mu_get_stat(NULL, argv[argc - 1], &sb))
if (S_ISDIR(sb.st_mode))
goto IF_EXSIST;
if (argc == 2)
ret = cptree(argv[0], argv[argc - 1]);
else {
IF_EXSIST:
for (int i = 0; i < argc - 1; i++) {
char *new_path = mu_make_path(f_flag, argv[argc - 1], basename(argv[i]));
if (new_path == NULL)
return 1;
if (cptree(argv[i], new_path))
ret = 1;
free(new_path);
}
}
return ret;
}

3
src/coreutils/date/build.sh Executable file
View file

@ -0,0 +1,3 @@
#!/bin/sh
project_dir=$(pwd)
echo ./*.c $CFLAGS -o $OUTPUT$(basename $project_dir) | xargs $CC

109
src/coreutils/date/date.c Normal file
View file

@ -0,0 +1,109 @@
#include <stdio.h>
#include <string.h>
#include <unistd.h>
#include <stdlib.h>
#include <errno.h>
#include <time.h>
#include <sys/stat.h>
#include "get_stat.h"
const char *fmts[] = {
"%R",
"%T",
"%m.%d-%R",
"%m.%d-%T",
"%Y.%m.%d-%R",
"%Y.%m.%d-%T",
"%Y-%m-%d %R %z",
"%Y-%m-%d %T %z",
"%T %d-%m-%Y",
"%H %d-%m-%Y",
"%Y-%m-%d %H",
"%Y-%m-%d",
"%d-%m-%Y"
};
time_t parse_date(char *str) {
time_t local = time(NULL);
struct tm *tm = localtime(&local);
for (size_t i = 0; i < sizeof(fmts) / sizeof(char *); i++) {
char *res = strptime(str, fmts[i], tm);
if (res && *res == '\0')
break;
}
time_t rt = mktime(tm);
if (rt == -1) {
fprintf(stderr, "date: %s\n", strerror(errno));
exit(1);
}
return rt;
}
int main(int argc, char **argv) {
time_t t = time(NULL);
char *fmt = "%a %b %e %H:%M:%S %Z %Y";
char *r_flag = 0;
/* For -s flag */
struct timespec ts;
int opt;
while ((opt = getopt(argc, argv, "s:d:r:u")) != -1) {
switch (opt) {
case 'r':
r_flag = optarg;
break;
case 's':
ts.tv_sec = parse_date(optarg);
if (clock_settime(CLOCK_REALTIME, &ts) < 0) {
fprintf(stderr, "date: %s\n", strerror(errno));
return 1;
}
return 0;
case 'd':
t = parse_date(optarg);
break;
case 'u':
if (setenv("TZ", "UTC0", 1) < 0) {
fprintf(stderr, "date: %s\n", strerror(errno));
return 1;
}
break;
default:
printf("date [rsdu] [+\"fmt\"]\n\t-s DATE Set new date\n\t-d DATE Print new date\n\t-u Work in UTC\n\t-r FILE Display last modification time of FILE\n");
return 0;
}
}
argv += optind;
argc -= optind;
if (argc != 0)
if (argv[0][0] == '+')
fmt = argv[0] + 1;
struct stat sb;
if (r_flag) {
if (mu_get_stat("date", r_flag, &sb))
return 1;
t = sb.st_mtime;
}
struct tm *tm = localtime(&t);
char buf[256];
strftime(buf, sizeof(buf), fmt, tm);
puts(buf);
return 0;
}

3
src/coreutils/dd/build.sh Executable file
View file

@ -0,0 +1,3 @@
#!/bin/sh
project_dir=$(pwd)
echo ./*.c $CFLAGS -o $OUTPUT$(basename $project_dir) | xargs $CC

249
src/coreutils/dd/dd.c Normal file
View file

@ -0,0 +1,249 @@
#include <fcntl.h>
#include <stdio.h>
#include <signal.h>
#include <string.h>
#include <stdlib.h>
#include <unistd.h>
#include <errno.h>
#include "human.h"
off_t infull, inpart;
off_t outfull, outpart;
off_t tbytes;
void summary(void) {
fprintf(stderr, "%jd+%jd records in\n", infull, inpart);
fprintf(stderr, "%jd+%jd records out\n", outfull, outpart);
fprintf(stderr, "%s total bytes copied\n", mu_humansize(tbytes, 1024));
}
int openfile(int flag, char *path, int mode) {
if (!strcmp(path, "-")) {
if (flag)
return STDOUT_FILENO;
return STDIN_FILENO;
}
int fd = open(path, mode, 0666);
if (fd < 0) {
fprintf(stderr, "dd: %s: %s\n", path, strerror(errno));
exit(1);
}
return fd;
}
off_t strtonum(char *str) {
char *p = NULL;
off_t res = strtoll(str, &p, 0);
if (str != p) {
if (!strcmp(p, "b"))
res *= 512;
else if (!strcmp(p, "m"))
res *= 1000000;
else if (!strcmp(p, "M"))
res *= 1048576;
else if (!strcmp(p, "K"))
res *= 1024;
else if (!strcmp(p, "k"))
res *= 1000;
else if (!strcmp(p, "g"))
res *= 1000000000;
else if (!strcmp(p, "G"))
res *= 1073741824;
}
if (res < 0)
res = 0;
return res;
}
int copy(int fd, void *buf, off_t len, off_t max) {
off_t n = write(fd, buf, len);
if (n < 0) {
fprintf(stderr, "dd: %s\n", strerror(errno));
return 1;
}
else if (n == max)
outfull++;
else if (n == len)
outpart++;
tbytes += n;
return 0;
}
int main(int argc, char **argv) {
signal(SIGPIPE, SIG_IGN);
char *ifp = "-";
char *ofp = "-";
off_t count = -1;
off_t skip = 0;
off_t seek = 0;
off_t bs = 0;
off_t ibs = 512;
off_t obs = 512;
int ofd = STDOUT_FILENO;
int ifd = STDIN_FILENO;
/* Return value */
int ret = 1;
for (int i = 1; i < argc; i++) {
char *arg = argv[i];
char *val = strchr(arg, '=');
if (val == NULL) {
printf("dd\n\tif=InputFile\n\tof=OutputFile\n\tbs=ibs and obs\n\tibs=Input buffer size\n\tobs=Output buffer size\n\tseek=Skip N obs-sized output blocks\n\tskip=Skip N ibs-sized output blocks\n\tcount=Copy only N input blocks\n\nN and BYTES may be followed by the following multiplicative\nsuffixes: w=2, b=512, k=1000, K=1024, m=1000*1000,\nM=1024*1024, g=1000*1000*1000, G=1024*1024*1024\n");
return 1;
}
*val = '\0';
val++;
/* Get value */
if (!strcmp(arg, "if"))
ifp = val;
else if (!strcmp(arg, "of"))
ofp = val;
else if (!strcmp(arg, "seek"))
seek = strtonum(val);
else if (!strcmp(arg, "skip"))
skip = strtonum(val);
else if (!strcmp(arg, "count"))
count = strtonum(val);
else if (!strcmp(arg, "bs"))
bs = strtonum(val);
else if (!strcmp(arg, "ibs"))
ibs = strtonum(val);
else if (!strcmp(arg, "obs"))
obs = strtonum(val);
}
if (bs) {
ibs = bs;
obs = bs;
}
/* Make input ibuffer */
char *ibuf = malloc(ibs);
if (ibuf == NULL) {
fprintf(stderr, "dd: %s\n", strerror(errno));
return 1;
}
char *obuf = NULL;
if (ibs != obs) {
obuf = malloc(obs);
if (obuf == NULL) {
free(ibuf);
fprintf(stderr, "dd: %s\n", strerror(errno));
return 1;
}
}
/* Open files. Input */
ifd = openfile(0, ifp, O_RDONLY);
if (skip) {
if (lseek(ifd, skip * ibs, SEEK_CUR) < 0)
goto CLOSE;
}
/* Output */
int oflag = O_WRONLY | O_CREAT;
if (seek)
oflag |= O_TRUNC;
ofd = openfile(1, ofp, oflag);
if (seek) {
if (ftruncate(ofd, seek * ibs) < 0 || lseek(ofd, seek * ibs, SEEK_SET) < 0) {
fprintf(stderr, "dd: %s\n", strerror(errno));
goto CLOSE;
}
}
/* dd */
off_t opos = 0;
while (1) {
if (count == infull + inpart)
break;
off_t n = read(ifd, ibuf, ibs);
if (n <= 0)
break;
else if (ibs == n)
infull++;
else
inpart++;
if (ibs == obs) {
if (copy(ofd, ibuf, n, ibs))
goto CLOSE;
}
else {
char *tmp = ibuf;
while (n) {
off_t i = obs - opos;
if (i > n)
i = n;
memcpy(obuf + opos, tmp, i);
n -= i;
tmp += i;
opos += i;
if (opos == obs) {
if (copy(ofd, obuf, obs, obs))
goto CLOSE;
opos = 0;
}
}
}
}
if (opos != 0) {
if (copy(ofd, obuf, obs, obs))
goto CLOSE;
}
/* End */
fsync(ofd);
summary();
ret = 0;
CLOSE:
free(ibuf);
if (ibs != obs)
free(obuf);
close(ifd);
close(ofd);
return ret;
}

3
src/coreutils/df/build.sh Executable file
View file

@ -0,0 +1,3 @@
#!/bin/sh
project_dir=$(pwd)
echo ./*.c $CFLAGS -o $OUTPUT$(basename $project_dir) | xargs $CC

95
src/coreutils/df/df.c Normal file
View file

@ -0,0 +1,95 @@
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <stdint.h>
#include <errno.h>
#include <unistd.h>
#include <mntent.h>
#include <sys/statvfs.h>
#include "human.h"
#include "config.h"
char a_flag;
char h_flag;
off_t block = 1024;
int main(int argc, char **argv) {
int opt;
while ((opt = getopt(argc, argv, "hHka")) != -1) {
switch (opt) {
case 'h':
h_flag = 1;
break;
case 'H':
h_flag = 1;
block = 1000;
break;
case 'a':
a_flag = 1;
break;
default:
printf("df [rHa]\n\t-h Human readable (1024)\n\t-a Show all\n\t-H Human readable (1000)\n");
return 0;
}
}
FILE *fp = setmntent("/proc/mounts", "r");
if (fp == NULL) {
fprintf(stderr, "df: %s\n", strerror(errno));
return 1;
}
if (h_flag)
puts("Filesystem Size Used Available Use% Mounted on");
else
puts("Filesystem Size Used Available Use% Mounted on");
int ret = 0;
struct mntent *me;
struct statvfs disk;
while ((me = getmntent(fp)) != NULL) {
if (!strcmp(me->mnt_fsname, "none"))
continue;
if (statvfs(me->mnt_dir, &disk) < 0) {
ret = 1;
continue;
}
if (!a_flag)
if (!strcmp(me->mnt_fsname, "/dev/root") || disk.f_blocks == 0)
continue;
off_t bs = disk.f_frsize / block;
off_t total = disk.f_blocks * bs;
off_t avail = disk.f_bfree * bs;
off_t used = total - avail;
off_t capacity = (used * 100 + 1) / (avail + used + 1);
if (!h_flag)
printf("%-20s %12jd %12jd %12jd %12jd%% %s\n", me->mnt_fsname, total, used, avail, capacity, me->mnt_dir);
else {
char total_s[MU_HUMAN_BUF_SIZE + 1];
char used_s[MU_HUMAN_BUF_SIZE + 1];
char avail_s[MU_HUMAN_BUF_SIZE + 1];
snprintf(total_s, sizeof(total_s), "%s", mu_humansize(total * block, block));
snprintf(used_s, sizeof(used_s), "%s", mu_humansize(used * block, block));
snprintf(avail_s, sizeof(avail_s), "%s", mu_humansize(avail * block, block));
printf("%-20s %10s %9s %9s %3jd%% %s\n", me->mnt_fsname, total_s, used_s, avail_s, capacity, me->mnt_dir);
}
}
endmntent(fp);
return ret;
}

3
src/coreutils/du/build.sh Executable file
View file

@ -0,0 +1,3 @@
#!/bin/sh
project_dir=$(pwd)
echo ./*.c $CFLAGS -o $OUTPUT$(basename $project_dir) | xargs $CC

111
src/coreutils/du/du.c Normal file
View file

@ -0,0 +1,111 @@
#include <stdio.h>
#include <errno.h>
#include <string.h>
#include <stdlib.h>
#include <unistd.h>
#include <dirent.h>
#include <stdint.h>
#include "get_stat.h"
#include "make_path.h"
#include "human.h"
char h_flag;
char s_flag;
char c_flag;
off_t total;
void print(off_t size, const char *filename) {
if (h_flag)
printf("%s\t%s\n", mu_humansize(size * 512, 1024), filename);
else
printf("%jd\t%s\n", (intmax_t)size / 2, filename);
}
off_t du(const char *path, int recurs_flag) {
struct stat sb;
if (mu_get_lstat("du", path, &sb))
return 0;
off_t sum = sb.st_blocks;
if (c_flag)
total += sum;
if (S_ISDIR(sb.st_mode)) {
DIR *dp = opendir(path);
if (!dp) {
fprintf(stderr, "du: %s\n", strerror(errno));
return 0;
}
struct dirent *ep;
while ((ep = readdir(dp)) != NULL) {
if (!strcmp(ep->d_name, ".") || !strcmp(ep->d_name, ".."))
continue;
char *new_path = mu_make_path("du", path, ep->d_name);
if (new_path == NULL)
return 0;
sum += du(new_path, 1);
free(new_path);
}
closedir(dp);
if (!s_flag && recurs_flag) {
print(sum, path);
return sum;
}
/* Silent mode */
else if (!recurs_flag)
print(sum, path);
}
else if (!recurs_flag)
print(sum, path);
return sum;
}
int main(int argc, char **argv) {
int opt;
while ((opt = getopt(argc, argv, "hsc")) != -1) {
switch (opt) {
case 'h':
h_flag = 1;
break;
case 's':
s_flag = 1;
break;
case 'c':
c_flag = 1;
break;
default:
printf("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\n");
return 0;
}
}
if (argv[optind] == NULL)
du(".", 0);
else {
argv += optind;
argc -= optind;
for (int i = 0; i < argc; i++)
du(argv[i], 0);
}
if (c_flag)
print(total, "total");
return 0;
}

3
src/coreutils/echo/build.sh Executable file
View file

@ -0,0 +1,3 @@
#!/bin/sh
project_dir=$(pwd)
echo ./*.c $CFLAGS -o $OUTPUT$(basename $project_dir) | xargs $CC

94
src/coreutils/echo/echo.c Normal file
View file

@ -0,0 +1,94 @@
#include <stdio.h>
#include <ctype.h>
#include <unistd.h>
#include <stdlib.h>
#include <string.h>
char n_flag = 0;
char e_flag = 0;
void format(char *str) {
for (size_t i = 0; i < strlen(str); i++) {
unsigned int c = str[i];
if (c == '\\') {
switch (str[i + 1]) {
case 'a':
c = '\a';
break;
case 'n':
c = '\n';
break;
case 't':
c = '\t';
break;
case 'c':
exit(0);
case 'v':
c = '\v';
break;
case 'r':
c = '\r';
break;
case 'f':
c = '\f';
break;
case 'e':
c = '\033';
break;
case 'b':
c = '\b';
break;
default:
c = '\\';
}
i++;
}
putchar(c);
}
}
int main(int argc, char **argv) {
argv++;
argc--;
for (int i = 0; i < argc; i++) {
if (argv[i][0] == '-') {
if (strstr(argv[i] + 1, "n"))
n_flag = 1;
else if (strstr(argv[i] + 1, "e"))
e_flag = 1;
argc--;
argv++;
}
}
for (int i = 0; i < argc; i++) {
if (e_flag)
format(argv[i]);
else
fputs(argv[i], stdout);
if (i < argc - 1)
putchar(' ');
}
if (!n_flag)
putchar('\n');
return 0;
}

3
src/coreutils/env/build.sh vendored Executable file
View file

@ -0,0 +1,3 @@
#!/bin/sh
project_dir=$(pwd)
echo ./*.c $CFLAGS -o $OUTPUT$(basename $project_dir) | xargs $CC

33
src/coreutils/env/env.c vendored Normal file
View file

@ -0,0 +1,33 @@
#include <errno.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
int main(const int argc, char **argv, const char **envp) {
int i;
for (i = 1; i < argc; i++) {
char *val = strchr(argv[i], '=');
if (!val)
break;
val[0] = '\0';
if (setenv(argv[i], val + 1, 1)) {
fprintf(stderr, "env: %s\n", strerror(errno));
return 1;
}
}
/* Print env */
if (i == argc) {
while (*envp)
puts(*envp++);
return 0;
}
execvp(argv[i], argv + i);
fprintf(stderr, "env: %s: %s\n", argv[i], strerror(errno));
return 1;
}

3
src/coreutils/false/build.sh Executable file
View file

@ -0,0 +1,3 @@
#!/bin/sh
project_dir=$(pwd)
echo ./*.c $CFLAGS -o $OUTPUT$(basename $project_dir) | xargs $CC

View file

@ -0,0 +1,3 @@
int main(void) {
return 1;
}

3
src/coreutils/head/build.sh Executable file
View file

@ -0,0 +1,3 @@
#!/bin/sh
project_dir=$(pwd)
echo ./*.c $CFLAGS -o $OUTPUT$(basename $project_dir) | xargs $CC

95
src/coreutils/head/head.c Normal file
View file

@ -0,0 +1,95 @@
#define _HEAD_C
#include <fcntl.h>
#include <stdio.h>
#include <errno.h>
#include <string.h>
#include <unistd.h>
#include <stdlib.h>
#include "config.h"
char v_flag;
char c_flag;
long parse_long(const char *str) {
char *ptr;
long ret = strtol(str, &ptr, 0);
if (*ptr) {
fprintf(stderr, "head: %s invalid number\n", ptr);
exit(1);
}
return ret;
}
void print(const char *file, FILE *fp, long lines, long bytes) {
if (v_flag)
printf(HEAD_FMT, file);
long lcount = 0;
long bcount = 0;
while (1) {
int c = getc(fp);
bcount++;
if (c == '\n')
lcount++;
if (c == EOF || lcount == lines || (c_flag && bcount == bytes))
break;
putchar(c);
}
}
int main(int argc, char **argv) {
long lines = 10;
long bytes = 0;
int opt;
while ((opt = getopt(argc, argv, "n:c:v")) != -1) {
switch (opt) {
case 'n':
lines = parse_long(optarg);
break;
case 'c':
c_flag = 1;
bytes = parse_long(optarg);
break;
case 'v':
v_flag = 1;
break;
default:
printf("head [ncv] [file1 file2...]\n\t-n Print N lines\n\t-c Print N bytes\n\t-v Print headers\n");
return 0;
}
}
argv += optind;
argc -= optind;
if (argc == 0)
print("-", stdin, lines, bytes);
for (int i = 0; i < argc; i++) {
FILE *fp = NULL;
if (argv[i][0] == '-')
fp = stdin;
else
fp = fopen(argv[i], "r");
if (fp == NULL) {
fprintf(stderr, "head: %s: %s\n", argv[i], strerror(errno));
return 1;
}
print(argv[i], fp, lines, bytes);
fclose(fp);
}
return 0;
}

3
src/coreutils/id/build.sh Executable file
View file

@ -0,0 +1,3 @@
#!/bin/sh
project_dir=$(pwd)
echo ./*.c $CFLAGS -o $OUTPUT$(basename $project_dir) | xargs $CC

130
src/coreutils/id/id.c Normal file
View file

@ -0,0 +1,130 @@
#include <grp.h>
#include <pwd.h>
#include <stdio.h>
#include <errno.h>
#include <errno.h>
#include <string.h>
#include <unistd.h>
#include <stdlib.h>
#include <limits.h>
#include <sys/types.h>
char g_flag;
char G_flag;
char n_flag;
char r_flag;
char u_flag;
int print_groups(const struct passwd *pwd, const char *fmt, const int flag) {
gid_t groups[NGROUPS_MAX];
int ngroups = NGROUPS_MAX;
if (getgrouplist(pwd->pw_name, pwd->pw_gid, groups, &ngroups) < 0)
return 1;
for (int i = 0; i < ngroups; i++) {
struct group *grp = getgrgid(groups[i]);
if (grp && !n_flag)
printf("%u", groups[i]);
if ((!r_flag && n_flag) || flag)
printf(fmt, grp->gr_name);
if (g_flag && i == 0)
break;
putchar(' ');
}
return 0;
}
int ids(uid_t uid, struct passwd *pwd) {
if (u_flag) {
if (n_flag)
printf("%s", pwd->pw_name);
else
printf("%u", uid);
}
else if (G_flag || g_flag)
print_groups(pwd, "%s", 0);
putchar('\n');
return 0;
}
int def_ids(uid_t uid, struct passwd *pwd) {
printf("uid=%d(%s) gid=%d", uid, pwd->pw_name, pwd->pw_gid);
struct group *grp = getgrgid(pwd->pw_gid);
if (grp)
printf("(%s)", grp->gr_name);
printf(" groups=");
print_groups(pwd, "(%s)", 1);
putchar('\n');
return 0;
}
void usage(int sig) {
printf("id [gGurn] [user]\n\t-u User ID\n\t-g Group ID\n\t-G Supplementary group IDs\n\t-n Print names instead of numbers\n\t-r Print real ID instead of effective ID\n");
exit(sig);
}
int main(int argc, char **argv) {
int opt;
while ((opt = getopt(argc, argv, "gGnru")) != -1) {
switch (opt) {
case 'g':
if (G_flag || u_flag)
usage(1);
g_flag = 1;
break;
case 'G':
if (g_flag || u_flag)
usage(1);
G_flag = 1;
break;
case 'u':
if (G_flag || g_flag)
usage(1);
u_flag = 1;
break;
case 'r':
r_flag = 1;
break;
case 'n':
n_flag = 1;
break;
default:
usage(0);
}
}
argv += optind;
argc -= optind;
uid_t uid = getuid();
struct passwd *pwd = getpwuid(uid);
if (argv[0] != NULL)
pwd = getpwnam(argv[0]);
if (!pwd) {
fprintf(stderr, "id: %s\n", strerror(errno));
return 1;
}
if (u_flag || G_flag || g_flag)
return ids(uid, pwd);
return def_ids(uid, pwd);
}

3
src/coreutils/ln/build.sh Executable file
View file

@ -0,0 +1,3 @@
#!/bin/sh
project_dir=$(pwd)
echo ./*.c $CFLAGS -o $OUTPUT$(basename $project_dir) | xargs $CC

76
src/coreutils/ln/ln.c Normal file
View file

@ -0,0 +1,76 @@
#include <stdio.h>
#include <errno.h>
#include <string.h>
#include <unistd.h>
#include "make_path.h"
char s_flag;
char f_flag;
char v_flag;
int ln(const char *src, const char *dst) {
if (f_flag)
if (unlink(dst) && v_flag)
fprintf(stderr, "ln: removed %s\n", dst);
int ret = 0;
if (s_flag)
ret = symlink(src, dst);
else
ret = link(src, dst);
if (!ret && v_flag)
fprintf(stderr, "ln: linked %s to %s\n", src, dst);
return ret;
}
int main(int argc, char **argv) {
int opt;
while ((opt = getopt(argc, argv, "sfv")) != -1) {
switch (opt) {
case 's':
s_flag = 1;
break;
case 'f':
f_flag = 1;
break;
case 'v':
v_flag = 1;
break;
default:
printf("ln [sfv] [src] [dst]\n\t-f Force\n\t-s Symbolic\n\t-v Verbose\n");
return 0;
}
}
argv += optind;
argc -= optind;
if (argc == 2) {
if (ln(argv[0], argv[1])) {
char *new_path = mu_make_path("ln", argv[1], argv[0]);
if (new_path == NULL)
return 1;
if (ln(argv[0], new_path)) {
free(new_path);
fprintf(stderr, "ln: %s %s\n", argv[1], strerror(errno));
return 1;
}
free(new_path);
}
}
else {
fprintf(stderr, "ln: missing operand\n");
return 1;
}
return 0;
}

3
src/coreutils/ls/build.sh Executable file
View file

@ -0,0 +1,3 @@
#!/bin/sh
project_dir=$(pwd)
echo ./*.c $CFLAGS -o $OUTPUT$(basename $project_dir) | xargs $CC

508
src/coreutils/ls/ls.c Normal file
View file

@ -0,0 +1,508 @@
#define _LS_C
#include <pwd.h>
#include <grp.h>
#include <time.h>
#include <stdio.h>
#include <errno.h>
#include <stdlib.h>
#include <string.h>
#include <stdint.h>
#include <unistd.h>
#include <dirent.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <sys/ioctl.h>
#include "mode_to_str.h"
#include "utf8_strlen.h"
#include "make_path.h"
#include "get_stat.h"
#include "config.h"
#include "human.h"
char O_flag;
char a_flag;
char l_flag;
char F_flag;
char c_flag;
char R_flag;
char d_flag;
char L_flag;
char h_flag;
char s_flag;
char i_flag;
char p_flag;
char nul_flag;
int sortd(const void *p1, const void *p2);
int (*sorter)(const void *p1, const void *p2) = sortd;
struct d_node {
/* basename */
char *name;
/* For free */
char *full_name;
struct d_node *next;
struct stat stats;
};
/* Work with dir */
struct d_node *stat_file(char *filename, const int lfile) {
/* lfile its flag. 1 if passed file from list_one() */
struct d_node *file = malloc(sizeof(struct d_node));
if (file == NULL) {
fprintf(stderr, "ls: malloc: %s\n", strerror(errno));
return NULL;
}
if (mu_get_stats("ls", !L_flag, filename, &file->stats)) {
free(file);
return NULL;
}
file->full_name = filename;
file->name = strrchr(filename, '/');
if (file->name == NULL || lfile)
file->name = filename;
else
file->name++;
return file;
}
void dfree(struct d_node **dir, const size_t files) {
for (size_t i = 0; i < files; i++) {
if (dir[i]->full_name != NULL)
free(dir[i]->full_name);
if (dir[i] != NULL)
free(dir[i]);
}
free(dir);
}
struct d_node **list(const char *path, off_t *total_size, size_t *nfiles, int *ret) {
DIR *dp = opendir(path);
if (dp == NULL) {
fprintf(stderr, "ls: %s: %s\n", path, strerror(errno));
return NULL;
}
struct d_node **dn = malloc(sizeof(struct d_node *));
if (dn == NULL) {
fprintf(stderr, "ls: malloc: %s\n", strerror(errno));
return NULL;
}
struct dirent *ep;
while ((ep = readdir(dp)) != NULL) {
if (ep->d_name[0] == '.' && !a_flag)
continue;
char *full_path = mu_make_path("ls", path, ep->d_name);
if (full_path == NULL)
continue;
struct d_node **bckp = realloc(dn, sizeof(struct d_node *) * (*nfiles + 1));
if (bckp == NULL) {
free(full_path);
dfree(dn, *nfiles);
closedir(dp);
fprintf(stderr, "ls: realloc: %s\n", strerror(errno));
return NULL;
}
dn = bckp;
dn[*nfiles] = stat_file(full_path, 0);
if (dn[*nfiles] == NULL) {
*ret = 1;
free(full_path);
continue;
}
*total_size += dn[*nfiles]->stats.st_blocks;
(*nfiles)++;
}
closedir(dp);
return dn;
}
char *get_date(const time_t mtime) {
static char date[100];
strftime(date, sizeof(date), "%b %d %H:%M", localtime(&mtime));
return date;
}
/* Print */
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)) {
if (node->name[strlen(node->name) - 1] != '/')
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)) {
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)) {
suf = '*';
color = LS_EXE_COLOR;
}
int ret = 0;
if (i_flag)
ret += printf("%7ju ", (uintmax_t)node->stats.st_ino);
if (s_flag) {
off_t size = 512 * node->stats.st_blocks;
if (h_flag)
ret += printf("%7s ", mu_humansize(size, 1024));
else
ret += printf("%7jd ", size / 1024);
}
if (l_flag) {
printf("%s", mode);
struct passwd *pw = getpwuid(node->stats.st_uid);
struct group *gr = getgrgid(node->stats.st_gid);
if (pw == NULL || gr == NULL) {
fprintf(stderr, "ls: print: %s\n", strerror(errno));
return -1;
}
if (h_flag)
ret += printf(" %4ju %4s %6s %6s %s ", (uintmax_t)node->stats.st_nlink, pw->pw_name, gr->gr_name, mu_humansize(node->stats.st_size, 1024), get_date(node->stats.st_mtime));
else
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 += utf8_strlen(node->name);
if (c_flag && p_flag)
printf("\033[0m");
if (F_flag)
printf("%c", suf);
return ret;
}
int col_print(struct d_node **node, const size_t files, const struct winsize w) {
/* Get max len */
size_t maxlen = 0;
for (size_t i = 0; i < files; i++) {
size_t len = utf8_strlen(node[i]->name);
if (len > maxlen)
maxlen = len;
}
/* Calc */
maxlen += 3;
if (i_flag)
maxlen += 10;
if (s_flag)
maxlen += 10;
size_t ncols = w.ws_col / maxlen;
size_t nrows = files;
if (ncols > 1) {
nrows = files / ncols;
if (nrows * ncols < files)
nrows++;
}
else
ncols = 1;
int col = 0;
int nexttab = 0;
/* Mc print */
for (size_t i = 0; i < nrows; i++) {
for (size_t j = 0; j < ncols; j++) {
size_t index = j * nrows + i;
if (index < files) {
if (col > 0) {
nexttab -= col;
col += nexttab;
for (int k = 0; k < nexttab; k++)
putchar(' ');
}
nexttab = col + (int)maxlen;
int ret = print(node[index]);
if (ret == -1)
return 1;
col += ret;
}
}
putchar((nul_flag) ? '\0' : '\n');
col = 0;
}
return 0;
}
int struct_print(struct d_node **dir, const size_t files, const struct winsize w) {
int ret = 0;
/* pipe print */
if (!p_flag || l_flag || O_flag) {
for (size_t i = 0; i < files; i++) {
if (print(dir[i]) == -1)
ret = 1;
putchar((nul_flag) ? '\0' : '\n');
}
}
else
if (col_print(dir, files, w))
ret = 1;
return ret;
}
/* Sort */
int sortt(const void *p1, const void *p2) {
return (*(struct d_node **)p2)->stats.st_mtime - (*(struct d_node **)p1)->stats.st_mtime;
}
int sorts(const void *p1, const void *p2) {
return (*(struct d_node **)p2)->stats.st_size - (*(struct d_node **)p1)->stats.st_size;
}
int sortd(const void *p1, const void *p2) {
return strcmp((*(struct d_node **)p1)->full_name, (*(struct d_node **)p2)->full_name);
}
/* Ls */
int ls_dir(const char *dir_name, const int label, const struct winsize w) {
if (dir_name == NULL)
return 0;
int ret = 0;
size_t files = 0;
off_t total_size = 0;
struct d_node **dir = list(dir_name, &total_size, &files, &ret);
/* Title */
if ((label || R_flag) && !d_flag)
printf("\n%s:\n", dir_name);
if (l_flag) {
if (h_flag)
printf("total: %s\n", mu_humansize(total_size * 512, 1024));
else
printf("total: %jd\n", (intmax_t)total_size / 2);
}
if (dir == NULL)
return 1;
qsort(dir, files, sizeof(struct d_node *), sorter);
if (struct_print(dir, files, w))
ret = 1;
if (R_flag)
for (size_t i = 0; i < files; i++)
if (S_ISDIR(dir[i]->stats.st_mode) && strcmp(dir[i]->name, "..") && strcmp(dir[i]->name, "."))
ls_dir(dir[i]->full_name, 1, w);
dfree(dir, files);
return ret;
}
int ls_files(int argc, char **argv, const struct winsize w) {
size_t files = 0;
struct d_node **file = malloc(sizeof(struct d_node *));
if (file == NULL) {
fprintf(stderr, "ls: malloc: %s\n", strerror(errno));
return 1;
}
int ret = 0;
for (int i = 0; i < argc; i++) {
struct stat sb;
if (mu_get_lstat("ls", argv[i], &sb)) {
ret = 1;
continue;
}
if (S_ISDIR(sb.st_mode))
continue;
struct d_node **tmp = realloc(file, sizeof(struct d_node *) * (files + 1));
if (tmp == NULL) {
dfree(file, files);
return 1;
}
file = tmp;
file[files] = stat_file(argv[i], 1);
if (file[files] == NULL) {
dfree(file, files);
ret = 1;
break;
}
files++;
argv[i] = NULL;
}
qsort(file, files, sizeof(struct d_node *), sorter);
if (struct_print(file, files, w))
ret = 1;
return ret;
}
int main(int argc, char **argv) {
int opt;
while ((opt = getopt(argc, argv, "1alFcRdLhistS0")) != -1) {
switch (opt) {
case '1':
O_flag = 1;
break;
case 'a':
a_flag = 1;
break;
case 'l':
l_flag = 1;
break;
case 'F':
F_flag = 1;
break;
case 'c':
c_flag = 1;
break;
case 'R':
d_flag = 0;
R_flag = 1;
break;
case 'd':
R_flag = 0;
d_flag = 1;
break;
case 'L':
L_flag = 1;
break;
case 'h':
h_flag = 1;
break;
case 'i':
i_flag = 1;
break;
case 's':
s_flag = 1;
break;
case 't':
sorter = sortt;
break;
case 'S':
sorter = sorts;
break;
case '0':
nul_flag = 1;
break;
default:
printf("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\n");
return 0;
}
}
argv += optind;
argc -= optind;
struct winsize w;
ioctl(STDOUT_FILENO, TIOCGWINSZ, &w);
/* Check if programm piped, 1 - false, 0 - true */
p_flag = isatty(STDOUT_FILENO);
int ret = 0;
if (ls_files(argc, argv, w))
ret = 1;
if (argc == 0) {
if (ls_dir(".", 0, w))
ret = 1;
}
else if (argc == 1) {
if (ls_dir(argv[0], 0, w))
ret = 1;
}
else {
for (int i = 0; i < argc; i++)
if (ls_dir(argv[i], 1, w))
ret = 1;
}
return ret;
}

3
src/coreutils/mkdir/build.sh Executable file
View file

@ -0,0 +1,3 @@
#!/bin/sh
project_dir=$(pwd)
echo ./*.c $CFLAGS -o $OUTPUT$(basename $project_dir) | xargs $CC

View file

@ -0,0 +1,85 @@
#include <sys/stat.h>
#include <libgen.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <errno.h>
#include "parse_mode.h"
char v_flag;
char p_flag;
mode_t mode = 0777;
int do_mkdir(const char *path) {
if (mkdir(path, mode)) {
if (p_flag)
return 0;
fprintf(stderr, "mkdir: %s: %s\n", path, strerror(errno));
return 1;
}
else if (v_flag)
printf("mkdir: %s created with mode %u\n", path, mode);
return 0;
}
int do_parents(const char *path) {
if (path[0] == '.' || path[0] == '/')
return 0;
char *path2 = strdup(path);
if (!path2) {
fprintf(stderr, "mkdir: %s: %s\n", path, strerror(errno));
return 1;
}
const char *par = dirname(path2);
do_parents(par);
int ret = do_mkdir(path2);
free(path2);
return ret;
}
int main(int argc, char **argv) {
int opt;
while ((opt = getopt(argc, argv, "pm:v")) != -1) {
switch (opt) {
case 'p':
p_flag = 1;
break;
case 'm':
mode = mu_parse_mode(optarg, 0);
break;
case 'v':
v_flag = 1;
break;
default:
printf("mkdir [pmv] [dst1 dst2...]\n\t-p Make parent dir\n\t-m MODE Mode\n\t-v Verbose\n");
return 0;
}
}
argv += optind;
argc -= optind;
for (int i = 0; i < argc; i++) {
if (p_flag) {
if (do_parents(argv[i]))
return 1;
}
else {
if (do_mkdir(argv[i]))
return 1;
}
}
return 0;
}

3
src/coreutils/mknod/build.sh Executable file
View file

@ -0,0 +1,3 @@
#!/bin/sh
project_dir=$(pwd)
echo ./*.c $CFLAGS -o $OUTPUT$(basename $project_dir) | xargs $CC

View file

@ -0,0 +1,81 @@
#ifdef __linux__
#include <sys/sysmacros.h>
#endif
#include <sys/stat.h>
#include <string.h>
#include <stdlib.h>
#include <unistd.h>
#include <errno.h>
#include <stdio.h>
#include "parse_mode.h"
long parse_long(const char *str) {
char *ptr = NULL;
long value = strtol(str, &ptr, 10);
if (*ptr) {
fprintf(stderr, "mknod: not a number: %s\n", str);
exit(1);
}
else if (value < 0) {
fprintf(stderr, "mknod: number is negative: %s\n", str);
exit(1);
}
return value;
}
int main(int argc, char **argv) {
mode_t mode = 0666;
int opt;
while ((opt = getopt(argc, argv, "m:")) != -1) {
switch (opt) {
case 'm':
mode = mu_parse_mode(optarg, 0);
break;
default:
printf("mknod [m] [NAME] [TYPE] [MAJOR MINOR]\n\t-m MODE\n\n");
printf("Types:\n\tb - block device\n\tc or u - character device\n\tp - named pipe/fifo (MAJOR MINOR must be omitted)\n\ts - socket\n");
return 0;
}
}
argv += optind;
argc -= optind;
if (argc <= 1) {
fprintf(stderr, "mknod: missing operand\n");
return 1;
}
dev_t dev = 0;
if (argc == 4)
dev = makedev(parse_long(argv[2]), parse_long(argv[3]));
if (!strncmp("b", argv[1], 1))
mode |= S_IFBLK;
else if (!strncmp("c", argv[1], 1) || !strncmp("u", argv[1], 1))
mode |= S_IFCHR;
else if (!strncmp("p", argv[1], 1))
mode |= S_IFIFO;
else if (!strncmp("s", argv[1], 1))
mode |= S_IFSOCK;
else {
fprintf(stderr, "mknod: unknow file type\n");
return 1;
}
if (mknod(argv[0], mode, dev) < 0) {
fprintf(stderr, "mknod: %s\n", strerror(errno));
return 1;
}
return 0;
}

3
src/coreutils/mktemp/build.sh Executable file
View file

@ -0,0 +1,3 @@
#!/bin/sh
project_dir=$(pwd)
echo ./*.c $CFLAGS -o $OUTPUT$(basename $project_dir) | xargs $CC

View file

@ -0,0 +1,98 @@
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <unistd.h>
#include <errno.h>
#include "make_path.h"
int make_temp_dir(char *tmp) {
if (!mkdtemp(tmp)) {
if (errno == EINVAL)
fprintf(stderr, "mktemp: template does not end in exactly 'XXXXX': %s\n", tmp);
else
fprintf(stderr, "mktemp: %s\n", strerror(errno));
return 1;
}
return 0;
}
int get_suffix(const char *str) {
size_t len = strlen(str);
for (size_t i = len - 1; i > 0; i--)
if (str[i] == 'X')
return len - i - 1;
return 0;
}
int make_temp_file(char *tmp) {
if (!strstr(tmp, "XXXXXX")) {
fprintf(stderr, "mktemp: too few X's in template: %s\n", tmp);
return 1;
}
int fd = mkstemps(tmp, get_suffix(tmp));
if (fd < 0) {
fprintf(stderr, "mktemp: %s\n", strerror(errno));
return 1;
}
close(fd);
return 0;
}
int main(int argc, char **argv) {
unsigned int d_flag = 0;
char *path = NULL;
int opt;
while ((opt = getopt(argc, argv, "dp:")) != -1) {
switch (opt) {
case 'd':
d_flag = 1;
break;
case 'p':
path = optarg;
break;
default:
printf("mktemp [dp] [file]\n\t-d Dir\n\t-p Base dir\n");
return 0;
}
}
argv += optind;
argc -= optind;
if (argc == 0 && path == NULL) {
path = getenv("TMPDIR");
if (!path || path[0] == '\0')
path = "/tmp/";
}
char *x = mu_make_path("mktemp", path, (argc == 0) ? "tmp.XXXXXX" : argv[0]);
if (x == NULL)
return 1;
if (d_flag) {
if (make_temp_dir(x)) {
free(x);
return 1;
}
}
else {
if (make_temp_file(x)) {
free(x);
return 1;
}
}
puts(x);
free(x);
return 0;
}

3
src/coreutils/mv/build.sh Executable file
View file

@ -0,0 +1,3 @@
#!/bin/sh
project_dir=$(pwd)
echo ./*.c $CFLAGS -o $OUTPUT$(basename $project_dir) | xargs $CC

62
src/coreutils/mv/mv.c Normal file
View file

@ -0,0 +1,62 @@
#include <stdio.h>
#include <errno.h>
#include <fcntl.h>
#include <libgen.h>
#include <string.h>
#include <stdlib.h>
#include <unistd.h>
#include "make_path.h"
char *f_flag = "mv";
int move(const char *src, const char *dst) {
char *copy = strdup(src);
if (!copy)
return 1;
char *new_path = mu_make_path(f_flag, dst, basename(copy));
if (new_path == NULL) {
free(copy);
return 1;
}
int ret = 0;
if (rename(src, new_path) < 0)
ret = 1;
free(new_path);
free(copy);
return ret;
}
int main(int argc, char **argv) {
int opt;
while ((opt = getopt(argc, argv, "f")) != -1) {
switch (opt) {
case 'f':
f_flag = NULL;
break;
default:
printf("mv [f] [src1 src2...] [dst]\n\t-f Force\n");
return 0;
}
}
argv += optind;
argc -= optind;
/* Move code */
for (int i = 0; i < argc - 1; i++) {
if (move(argv[i], argv[argc - 1])) {
if (rename(argv[i], argv[argc - 1]) < 0) {
if (f_flag)
fprintf(stderr, "mv: %s %s\n", argv[i], strerror(errno));
return 1;
}
}
}
return 0;
}

3
src/coreutils/nice/build.sh Executable file
View file

@ -0,0 +1,3 @@
#!/bin/sh
project_dir=$(pwd)
echo ./*.c $CFLAGS -o $OUTPUT$(basename $project_dir) | xargs $CC

43
src/coreutils/nice/nice.c Normal file
View file

@ -0,0 +1,43 @@
#include <stdio.h>
#include <errno.h>
#include <string.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/resource.h>
int main(int argc, char **argv) {
int oldp = getpriority(PRIO_PROCESS, 0);
int adj = 10;
int opt;
while ((opt = getopt(argc, argv, "n:")) != -1) {
switch (opt) {
case 'n':
adj = atoi(optarg);
break;
default:
printf("nice [n] [cmd] [arg1] [arg2]\n\t-n N Add N to the niceness\n");
return 0;
}
}
argv += optind;
argc -= optind;
if (argc == 0) {
printf("%d\n", oldp);
return 0;
}
if (setpriority(PRIO_PROCESS, 0, oldp + adj) < 0) {
fprintf(stderr, "nice: %s\n", strerror(errno));
return 1;
}
execvp(argv[0], argv);
fprintf(stderr, "nice: %s: %s\n", argv[0], strerror(errno));
return 1;
}

3
src/coreutils/nohup/build.sh Executable file
View file

@ -0,0 +1,3 @@
#!/bin/sh
project_dir=$(pwd)
echo ./*.c $CFLAGS -o $OUTPUT$(basename $project_dir) | xargs $CC

View file

@ -0,0 +1,42 @@
#include <stdio.h>
#include <fcntl.h>
#include <errno.h>
#include <string.h>
#include <signal.h>
#include <unistd.h>
#include "unused.h"
int main(int argc, char **argv) {
if (argc < 2) {
printf("nohup: missing operand\nnohup [cmd]\n");
return 0;
}
if (fork() != 0)
return 0;
signal(SIGHUP, SIG_IGN);
if (isatty(STDOUT_FILENO)) {
int fd = open("nohup.out", O_WRONLY | O_APPEND | O_CREAT, S_IRUSR | S_IWUSR);
if (fd < 0) {
fprintf(stderr, "nohup: nohup.out: %s\n", strerror(errno));
return 1;
}
if (dup2(fd, STDOUT_FILENO) < 0)
fprintf(stderr, "nohup: %s\n", strerror(errno));
close(fd);
}
if (isatty(STDERR_FILENO))
if (dup2(STDOUT_FILENO, STDERR_FILENO) < 0)
fprintf(stderr, "nohup: %s\n", strerror(errno));
argv++;
execvp(argv[0], argv);
fprintf(stderr, "nohup: %s: %s\n", argv[0], strerror(errno));
return 1;
}

3
src/coreutils/nproc/build.sh Executable file
View file

@ -0,0 +1,3 @@
#!/bin/sh
project_dir=$(pwd)
echo ./*.c $CFLAGS -o $OUTPUT$(basename $project_dir) | xargs $CC

View file

@ -0,0 +1,11 @@
#include <stdio.h>
#include <unistd.h>
int main(void) {
long count = sysconf(_SC_NPROCESSORS_ONLN);
if (count <= 0)
count = 1;
printf("%ld\n", count);
return 0;
}

View file

@ -0,0 +1,3 @@
#!/bin/sh
project_dir=$(pwd)
echo ./*.c $CFLAGS -o $OUTPUT$(basename $project_dir) | xargs $CC

View file

@ -0,0 +1,40 @@
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
int printvars(int len, char **names) {
int ret = 0;
for (int i = 0; i < len; i++) {
char *val = getenv(names[i]);
if (!val) {
ret = 1;
continue;
}
printf("%s\n", val);
}
return ret;
}
int main(int argc, char **argv, const char **envp) {
int opt;
while ((opt = getopt(argc, argv, "0")) != -1) {
printf("printenv [var1 var2...]\n");
return 0;
}
argv += optind;
argc -= optind;
if (argc == 0)
while (*envp)
printf("%s\n", *envp++);
else
return printvars(argc, argv);
return 0;
}

3
src/coreutils/pwd/build.sh Executable file
View file

@ -0,0 +1,3 @@
#!/bin/sh
project_dir=$(pwd)
echo ./*.c $CFLAGS -o $OUTPUT$(basename $project_dir) | xargs $CC

19
src/coreutils/pwd/pwd.c Normal file
View file

@ -0,0 +1,19 @@
#include <stdio.h>
#include <unistd.h>
#include <string.h>
#include <limits.h>
#include <errno.h>
int main(void) {
char cwd[PATH_MAX];
if (getcwd(cwd, sizeof(cwd)))
puts(cwd);
else {
fprintf(stderr, "pwd: %s\n", strerror(errno));
return 1;
}
return 0;
}

View file

@ -0,0 +1,3 @@
#!/bin/sh
project_dir=$(pwd)
echo ./*.c $CFLAGS -o $OUTPUT$(basename $project_dir) | xargs $CC

View file

@ -0,0 +1,48 @@
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <unistd.h>
#include <limits.h>
#include <errno.h>
int main(int argc, char **argv) {
char n_flag = 0;
int opt;
while ((opt = getopt(argc, argv, "n")) != -1) {
switch (opt) {
case 'n':
n_flag = 1;
break;
default:
printf("readlink [n] [file1 file2...]\n\t-n Don't add newline\n");
return 0;
}
}
argv += optind;
argc -= optind;
for (int i = 0; i < argc; i++) {
char path[PATH_MAX + 1];
ssize_t r = readlink(argv[i], path, sizeof(path));
if (r < 0) {
fprintf(stderr, "readlink: %s: %s\n", argv[i], strerror(errno));
return 1;
}
if (r > (ssize_t)sizeof(path)) {
fprintf(stderr, "readlink: %s: path too long\n", argv[i]);
return 1;
}
if (n_flag)
fputs(path, stdout);
else
puts(path);
}
return 0;
}

3
src/coreutils/renice/build.sh Executable file
View file

@ -0,0 +1,3 @@
#!/bin/sh
project_dir=$(pwd)
echo ./*.c $CFLAGS -o $OUTPUT$(basename $project_dir) | xargs $CC

View file

@ -0,0 +1,73 @@
#include <pwd.h>
#include <stdio.h>
#include <errno.h>
#include <string.h>
#include <unistd.h>
#include <stdlib.h>
#include <sys/resource.h>
int renice(int which, int who, int adj) {
adj += getpriority(which, who);
if (setpriority(which, who, adj)) {
fprintf(stderr, "renice: %s\n", strerror(errno));
return 1;
}
return 0;
}
int main(int argc, char **argv) {
int adj = 10;
int which = PRIO_PROCESS;
int opt;
while ((opt = getopt(argc, argv, "n:gup")) != -1) {
switch (opt) {
case 'n':
adj = atoi(optarg);
break;
case 'g':
which = PRIO_PGRP;
break;
case 'u':
which = PRIO_USER;
break;
case 'p':
which = PRIO_PROCESS;
break;
default:
printf("renice [ngup] [id1 id2...]\n\t-n N Add N to the niceness\n\t-g Process group ids\n\t-u Process user names\n\t-p Process ids\n");
return 0;
}
}
argv += optind;
argc -= optind;
int who = 0;
int ret = 0;
for (int i = 0; i < argc; i++) {
if (which == PRIO_USER) {
struct passwd *pw = getpwnam(argv[i]);
if (pw == 0) {
fprintf(stderr, "renice: %s\n", strerror(errno));
return 1;
}
who = pw->pw_uid;
}
else
who = atoi(argv[i]);
if (renice(which, who, adj))
ret = 1;
}
return ret;
}

3
src/coreutils/rm/build.sh Executable file
View file

@ -0,0 +1,3 @@
#!/bin/sh
project_dir=$(pwd)
echo ./*.c $CFLAGS -o $OUTPUT$(basename $project_dir) | xargs $CC

112
src/coreutils/rm/rm.c Normal file
View file

@ -0,0 +1,112 @@
#include <stdio.h>
#include <errno.h>
#include <string.h>
#include <stdlib.h>
#include <dirent.h>
#include <unistd.h>
#include <ctype.h>
#include "make_path.h"
#include "get_stat.h"
#include "recurse.h"
#include "unused.h"
char *f_flag = "rm";
char r_flag;
char v_flag;
int verbose(const char *path) {
if (v_flag) {
fprintf(stderr, "rm: remove %s? [y/n] ", path);
fflush(stderr);
int c = 0;
int key = 0;
while ((c = fgetc(stdin)) != EOF && c != '\n') {
if (c == 'y')
key = 1;
}
return key;
}
return 1;
}
void handle_error(const char *path) {
if (f_flag)
fprintf(stderr, "rm: %s: %s\n", path, strerror(errno));
}
int rm(const char *path, void *p) {
UNUSED(p);
if (verbose(path) && remove(path) < 0) {
handle_error(path);
return 1;
}
return 0;
}
int rmd(const char *path, void *p) {
UNUSED(p);
if (verbose(path) && rmdir(path) < 0) {
handle_error(path);
return 1;
}
return 0;
}
int main(int argc, char **argv) {
int opt;
while ((opt = getopt(argc, argv, "frRi")) != -1) {
switch (opt) {
case 'f':
f_flag = NULL;
break;
case 'r':
r_flag = 1;
break;
case 'i':
v_flag = 1;
break;
default:
printf("rm [rif] [file1 file2...]\n\t-f Force\n\t-r Recursive\n\t-i Print prompt before remove\n");
return 0;
}
}
argc -= optind;
argv += optind;
if (argc == 0) {
fprintf(stderr, "rm: missing operand\n");
return 1;
}
int ret = 0;
for (int i = 0; i < argc; i++) {
if (!strcmp(argv[i], ".") || !strcmp(argv[i], "..")){
printf("rm: refusing to remove '.' or '..' directory\n");
break;
}
if (r_flag) {
if (mu_recurse(f_flag, 1, argv[i], NULL, rm, rmd))
ret = 1;
}
else
if (rm(argv[i], NULL))
ret = 1;
}
return ret;
}

3
src/coreutils/seq/build.sh Executable file
View file

@ -0,0 +1,3 @@
#!/bin/sh
project_dir=$(pwd)
echo ./*.c $CFLAGS -o $OUTPUT$(basename $project_dir) | xargs $CC

58
src/coreutils/seq/seq.c Normal file
View file

@ -0,0 +1,58 @@
#include <stdio.h>
#include <errno.h>
#include <string.h>
#include <unistd.h>
#include <stdlib.h>
double parse_double(const char *str) {
char *ptr;
double res = strtod(str, &ptr);
if (*ptr) {
fprintf(stderr, "seq: %s: cant parse\n", ptr);
exit(1);
}
return res;
}
int main(int argc, char **argv) {
double start = 1;
double last = 0;
double n = 1;
argv++;
argc--;
switch (argc) {
case 1:
last = parse_double(argv[0]);
break;
case 2:
start = parse_double(argv[0]);
last = parse_double(argv[1]);
break;
case 3:
n = parse_double(argv[1]);
start = parse_double(argv[0]);
last = parse_double(argv[2]);
break;
default:
fprintf(stderr, "seq: missing operands\n");
return 1;
}
if (start <= last && n >= 0) {
for (double i = start; i <= last; i += n)
printf("%g\n", i);
}
else if (n <= 0)
for (double i = start; i >= last; i += n)
printf("%g\n", i);
return 0;
}

3
src/coreutils/setsid/build.sh Executable file
View file

@ -0,0 +1,3 @@
#!/bin/sh
project_dir=$(pwd)
echo ./*.c $CFLAGS -o $OUTPUT$(basename $project_dir) | xargs $CC

View file

@ -0,0 +1,21 @@
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <errno.h>
#include <unistd.h>
#include "unused.h"
int main(int argc, char **argv) {
UNUSED(argc);
if (argv[1] == NULL) {
printf("setsid [cmd] [arg1 arg2...]\n");
return 1;
}
if (fork() != 0)
return 0;
setsid();
execvp(argv[1], argv + 1);
}

3
src/coreutils/shred/build.sh Executable file
View file

@ -0,0 +1,3 @@
#!/bin/sh
project_dir=$(pwd)
echo ./*.c $CFLAGS -o $OUTPUT$(basename $project_dir) | xargs $CC

113
src/coreutils/shred/shred.c Normal file
View file

@ -0,0 +1,113 @@
#define _SHRED_C
#include <stdio.h>
#include <errno.h>
#include <fcntl.h>
#include <unistd.h>
#include <stdlib.h>
#include <string.h>
#include <sys/mman.h>
#include <sys/stat.h>
#include "config.h"
char f_flag;
char u_flag;
char z_flag;
int n_loops = 3;
int shred(int rand_fd, int fd) {
/* Get size */
off_t size = lseek(fd, 0, SEEK_END);
if (size <= 0)
return 1;
void *buf = mmap(NULL, size, PROT_WRITE, MAP_SHARED, fd, 0);
if (buf == MAP_FAILED) {
fprintf(stderr, "shred: mmap: %s\n", strerror(errno));
return 1;
}
for (char n = 0; n < n_loops; n++) {
if (read(rand_fd, buf, size) == 0)
fprintf(stderr, "shred: %s", strerror(errno));
fsync(fd);
}
if (z_flag)
memset(buf, 0, size);
if (munmap(buf, size)) {
fprintf(stderr, "shred: munmap: %s\n", strerror(errno));
return 1;
}
return 0;
}
int main(int argc, char **argv) {
int opt;
while ((opt = getopt(argc, argv, "fuzn:")) != -1) {
switch (opt) {
case 'f':
f_flag = 1;
break;
case 'u':
u_flag = 1;
break;
case 'z':
z_flag = 1;
break;
case 'n':
n_loops = atoi(optarg);
break;
default:
printf("shred [fuzn] [file1 file2...]\n\t-n N Overwrite N times, default 3\n\t-z Final overwrite with zeros\n\t-u Remove file\n\t-f Chmod to ensure writability\n");
return 0;
}
}
argv += optind;
argc -= optind;
if (argc == 0) {
fprintf(stderr, "shred: missing operand\n");
return 1;
}
int rand_fd = open(RAND_SOURCE, O_RDONLY);
if (rand_fd < 0) {
fprintf(stderr, "shred: %s: %s\n", RAND_SOURCE, strerror(errno));
return 1;
}
for (int i = 0; i < argc; i++) {
int fd = open(argv[i], O_RDWR);
if (fd < 0) {
fprintf(stderr, "shred: %s is %s\n", argv[i], strerror(errno));
continue;
}
shred(rand_fd, fd);
fsync(fd);
close(fd);
if (f_flag) {
if (chmod(argv[i], 0) < 0)
fprintf(stderr, "shred: %s is %s\n", argv[i], strerror(errno));
}
if (u_flag) {
if (unlink(argv[i]) < 0)
fprintf(stderr, "shred: %s is %s\n", argv[i], strerror(errno));
}
}
close(rand_fd);
return 0;
}

3
src/coreutils/sleep/build.sh Executable file
View file

@ -0,0 +1,3 @@
#!/bin/sh
project_dir=$(pwd)
echo ./*.c $CFLAGS -o $OUTPUT$(basename $project_dir) | xargs $CC

View file

@ -0,0 +1,29 @@
#include <stdio.h>
#include <limits.h>
#include <string.h>
#include <stdlib.h>
#include <unistd.h>
#include "duration.h"
int main(int argc, char **argv) {
int opt;
while ((opt = getopt(argc, argv, "")) != -1 || argc == 1) {
printf("sleep [num[SUFFIX]] or [inf Infinity]\nSUFFIXES:\n\tm - minute\n\th - hour\n\td - days\n");
return 0;
}
argv += optind;
argc -= optind;
if (!strncasecmp(argv[0], "inf", 3))
while (1)
sleep(INT_MAX);
unsigned long long usec = 0;
for (int i = 0; i < argc; i++)
usec += mu_parse_duration(argv[i]);
usleep(usec);
return 0;
}

3
src/coreutils/split/build.sh Executable file
View file

@ -0,0 +1,3 @@
#!/bin/sh
project_dir=$(pwd)
echo ./*.c $CFLAGS -o $OUTPUT$(basename $project_dir) | xargs $CC

119
src/coreutils/split/split.c Normal file
View file

@ -0,0 +1,119 @@
#include <fcntl.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <errno.h>
#include "config.h"
FILE *next_file(FILE *old, int x, int slen, char *prefix) {
if (old != NULL)
fclose(old);
/* Gen file name */
char name[BUF_SIZE + 1];
int len = snprintf(name, sizeof(name), "%s", prefix);
for (int i = slen; i >= 0; i--) {
if (len + i >= (int)(BUF_SIZE * sizeof(char)))
break;
name[len + i] = 'a' + (x % 26);
x /= 26;
}
/* Open file */
FILE *fp = fopen(name, "w");
if (fp == NULL) {
fprintf(stderr, "split: %s\n", strerror(errno));
return NULL;
}
return fp;
}
int main(int argc, char **argv) {
off_t size = 0;
int a_flag = 1;
int b_flag = 0;
char *prefix = "x";
int opt;
while ((opt = getopt(argc, argv, "l:a:b:")) != -1) {
switch (opt) {
case 'a':
a_flag = atoi(optarg);
break;
case 'l':
size = atoi(optarg);
break;
case 'b':
switch (optarg[strlen(optarg) - 1]) {
case 'm':
sscanf(optarg, "%ld", &size);
size *= 1048576;
break;
case 'k':
sscanf(optarg, "%ld", &size);
size *= 1024;
break;
default:
sscanf(optarg, "%ld", &size);
break;
}
b_flag = 1;
break;
default:
printf("split [alb] [file1]\n\t-l N Split by N lines\n\t-a N Use N letters as prefix\n\t-b N[k|m] Split by N (kilo|mega)bytes\n");
return 0;
}
}
argv += optind;
argc -= optind;
FILE *fp = stdin;
if (argv[0] != NULL && strcmp(argv[0], "-")) {
fp = fopen(argv[0], "r");
if (fp == NULL) {
fprintf(stderr, "split: %s: %s\n", argv[0], strerror(errno));
return 1;
}
}
if (argc == 2 && argv[1] != NULL)
prefix = argv[1];
int ret = 0;
int files = 0;
FILE *out = NULL;
off_t n = 0;
int ch;
while ((ch = getc(fp)) != EOF) {
if (out == NULL || n >= size) {
out = next_file(out, files++, a_flag, prefix);
if (out == NULL) {
ret = 1;
break;
}
n = 0;
}
if (ch == '\n' || b_flag)
n++;
putc(ch, out);
}
fclose(fp);
return ret;
}

3
src/coreutils/sync/build.sh Executable file
View file

@ -0,0 +1,3 @@
#!/bin/sh
project_dir=$(pwd)
echo ./*.c $CFLAGS -o $OUTPUT$(basename $project_dir) | xargs $CC

View file

@ -0,0 +1,6 @@
#include <unistd.h>
int main(void) {
sync();
return 0;
}

3
src/coreutils/tee/build.sh Executable file
View file

@ -0,0 +1,3 @@
#!/bin/sh
project_dir=$(pwd)
echo ./*.c $CFLAGS -o $OUTPUT$(basename $project_dir) | xargs $CC

61
src/coreutils/tee/tee.c Normal file
View file

@ -0,0 +1,61 @@
#include <fcntl.h>
#include <stdio.h>
#include <errno.h>
#include <string.h>
#include <signal.h>
#include <unistd.h>
#include <stdlib.h>
#include "config.h"
int main(int argc, char **argv) {
int flag = O_TRUNC;
int opt;
while ((opt = getopt(argc, argv, "ai")) != -1) {
switch (opt) {
case 'a':
flag = O_APPEND;
break;
case 'i':
signal(SIGINT, SIG_IGN);
break;
default:
printf("tee [ai] [file]\n\t-a Append\n\t-i Ignore interrupt signals\n");
return 0;
}
}
argv += optind;
argc -= optind;
int fd = STDOUT_FILENO;
if (argc > 0 && strcmp(argv[0], "-")) {
fd = open(argv[0], O_WRONLY | flag | O_CREAT, 0666);
if (fd < 0) {
fprintf(stderr, "tee: %s\n", strerror(errno));
return 1;
}
}
char buf[BUF_SIZE + 1];
ssize_t bytes = 0;
while ((bytes = read(STDIN_FILENO, buf, sizeof(buf)))) {
int stat = write(STDOUT_FILENO, buf, bytes);
int stat2 = bytes;
if (argc > 0)
stat2 = write(fd, buf, bytes);
if (stat != bytes || stat2 != bytes) {
fprintf(stderr, "tee: %s\n", strerror(errno));
return 1;
}
}
if (argc > 0 && strcmp(argv[0], "-"))
close(fd);
return 0;
}

3
src/coreutils/time/build.sh Executable file
View file

@ -0,0 +1,3 @@
#!/bin/sh
project_dir=$(pwd)
echo ./*.c $CFLAGS -o $OUTPUT$(basename $project_dir) | xargs $CC

56
src/coreutils/time/time.c Normal file
View file

@ -0,0 +1,56 @@
#include <stdio.h>
#include <errno.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <sys/wait.h>
#include <sys/times.h>
int main(int argc, char **argv) {
if (argc < 2) {
printf("time: missing operand\ntime [cmd]\n");
return 0;
}
long ticks = sysconf(_SC_CLK_TCK);
if (ticks <= 0) {
fprintf(stderr, "time: %s\n", strerror(errno));
return 1;
}
static struct tms tms;
clock_t r1 = times(&tms);
if (r1 == (clock_t)-1) {
fprintf(stderr, "time: %s\n", strerror(errno));
return 1;
}
/* Run */
pid_t pid;
if ((pid = fork()) == 0) {
execvp(argv[1], argv + 1);
exit(1);
}
int status = 0;
waitpid(pid, &status, 0);
/* Get time */
clock_t r2 = times(&tms);
if (r2 == (clock_t)-1) {
fprintf(stderr, "time: %s\n", strerror(errno));
return 1;
}
/* Print */
long real = (r2 - r1) / ticks;
long user = tms.tms_cutime / ticks;
long sys = tms.tms_cstime / ticks;
fprintf(stderr, "real:\t%ldm %ld.%lds\nsys:\t%ldm %ld.%lds\nuser:\t%ldm %ld.%lds\n", real / 60, real % 60, (r2 - r1) % 100, sys / 60, sys % 60, tms.tms_cstime % 100, user / 60, user % 60, tms.tms_cutime % 100);
if (status != 0)
printf("Proccess returned %d\n", status);
return 0;
}

3
src/coreutils/touch/build.sh Executable file
View file

@ -0,0 +1,3 @@
#!/bin/sh
project_dir=$(pwd)
echo ./*.c $CFLAGS -o $OUTPUT$(basename $project_dir) | xargs $CC

147
src/coreutils/touch/touch.c Normal file
View file

@ -0,0 +1,147 @@
#include <fcntl.h>
#include <stdlib.h>
#include <unistd.h>
#include <utime.h>
#include <errno.h>
#include <stdio.h>
#include <string.h>
#include <time.h>
char c_flag;
char m_flag;
char a_flag;
int setdate(const char *path, const time_t date, char flag) {
struct utimbuf new_time;
if (flag || a_flag)
new_time.actime = date;
if (flag || m_flag)
new_time.modtime = date;
if (utime(path, &new_time) < 0) {
fprintf(stderr, "touch: %s: %s\n", path, strerror(errno));
return 1;
}
return 0;
}
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));
return 1;
}
close(fd);
}
/* Update the date to now */
if (setdate(path, time(NULL), 1))
return 1;
/* Seting custom values */
char flag = 0;
if (m_flag == 0 && a_flag == 0)
flag = 1;
if (date != -1 && setdate(path, date, flag))
return 1;
return 0;
}
time_t parse_date(char *str) {
char *fmt = NULL;
switch (strlen(str)) {
case 8:
fmt = "%m%d%H%M";
break;
case 10:
fmt = "%y%m%d%H%M";
break;
case 11:
fmt = "%m%d%H%M.%S";
break;
case 12:
fmt = "%Y%m%d%H%M";
break;
case 13:
fmt = "%y%m%d%H%M.%S";
break;
case 15:
fmt = "%Y%m%d%H%M.%S";
break;
case 19:
fmt = "%Y-%m-%dT%H:%M:%S";
break;
default:
fprintf(stderr, "touch: invalid date format\n");
exit(1);
}
time_t now = time(NULL);
struct tm tm = *localtime(&now);
if (!strptime(str, fmt, &tm)) {
fprintf(stderr, "touch: %s\n", strerror(errno));
exit(1);
}
return mktime(&tm);
}
int main(int argc, char **argv) {
time_t date = -1;
int opt;
while ((opt = getopt(argc, argv, "cmad:t:")) != -1) {
switch (opt) {
case 'm':
m_flag = 1;
break;
case 'a':
a_flag = 1;
break;
case 'c':
c_flag = 1;
break;
case 't':
case 'd':
date = parse_date(optarg);
break;
default:
printf("touch [cmad] [file1 file2...]\n\t-c Don't create files\n\t-a Change only atime\n\t-m Change only mtime\n\t-d Date/time to use\n");
return 0;
}
}
argv += optind;
argc -= optind;
if (argc == 0) {
printf("touch: missing operand\n");
return 1;
}
for (int i = 0; i < argc; i++)
if (touch(argv[i], date))
return 1;
return 0;
}

3
src/coreutils/true/build.sh Executable file
View file

@ -0,0 +1,3 @@
#!/bin/sh
project_dir=$(pwd)
echo ./*.c $CFLAGS -o $OUTPUT$(basename $project_dir) | xargs $CC

View file

@ -0,0 +1,3 @@
int main(void) {
return 0;
}

3
src/coreutils/tty/build.sh Executable file
View file

@ -0,0 +1,3 @@
#!/bin/sh
project_dir=$(pwd)
echo ./*.c $CFLAGS -o $OUTPUT$(basename $project_dir) | xargs $CC

13
src/coreutils/tty/tty.c Normal file
View file

@ -0,0 +1,13 @@
#include <unistd.h>
#include <stdio.h>
int main(void) {
char *tty = ttyname(STDIN_FILENO);
if (tty)
puts(tty);
else
puts("not a tty");
return tty == NULL;
}

3
src/coreutils/uname/build.sh Executable file
View file

@ -0,0 +1,3 @@
#!/bin/sh
project_dir=$(pwd)
echo ./*.c $CFLAGS -o $OUTPUT$(basename $project_dir) | xargs $CC

132
src/coreutils/uname/uname.c Normal file
View file

@ -0,0 +1,132 @@
#define UNAME_C
#include <stdio.h>
#include <errno.h>
#include <string.h>
#include <unistd.h>
#include <sys/utsname.h>
#include "config.h"
#if defined(OS_NAME)
#elif defined(__ANDROID__)
#define OS_NAME "Android"
#elif defined(__linux__)
#define OS_NAME "Linux"
#elif defined(__OpenBSD__)
#define OS_NAME "OpenBSD"
#elif defined(__FreeBSD_)
#define OS_NAME "FreeBSD"
#elif defined(__NetBSD_)
#define OS_NAME "NetBSD"
#else
#define OS_NAME "unknow"
#endif
enum {
SYSNAME,
NODENAME,
RELEASE,
VERSION,
MACHINE,
OS,
CPU,
ALL,
COUNT
};
char flags[COUNT];
unsigned int counter = 0;
void print(const char *msg) {
if (counter > 0 && !flags[ALL])
putchar(' ');
printf("%s", msg);
counter++;
if (flags[ALL] && counter <= COUNT)
putchar(' ');
}
int main(int argc, char **argv) {
struct utsname uts;
if (uname(&uts)) {
fprintf(stderr, "uname: %s", strerror(errno));
return 1;
}
if (argc == 1) {
printf("%s\n", uts.sysname);
return 0;
}
int opt;
while ((opt = getopt(argc, argv, "asnrvmop")) != -1) {
switch (opt) {
case 'a':
flags[ALL] = 1;
break;
case 's':
flags[SYSNAME] = 1;
break;
case 'n':
flags[NODENAME] = 1;
break;
case 'r':
flags[RELEASE] = 1;
break;
case 'v':
flags[VERSION] = 1;
break;
case 'm':
flags[MACHINE] = 1;
break;
case 'o':
flags[OS] = 1;
break;
case 'p':
flags[CPU] = 1;
break;
default:
printf("uname [asnrvmop]\n\t-a All\n\t-s Sys\n\t-n Nodename\n\t-r Release\n\t-v Version\n\t-m Machine\n\t-o Os name\n");
return 0;
}
}
if (flags[SYSNAME] || flags[ALL])
print(uts.sysname);
if (flags[NODENAME] || flags[ALL])
print(uts.nodename);
if (flags[RELEASE] || flags[ALL])
print(uts.release);
if (flags[VERSION] || flags[ALL])
print(uts.version);
if (flags[MACHINE] || flags[ALL])
print(uts.machine);
if (flags[OS] || flags[ALL])
print(OS_NAME);
if (flags[CPU] || flags[ALL])
print("unknow");
putchar('\n');
}

3
src/coreutils/wc/build.sh Executable file
View file

@ -0,0 +1,3 @@
#!/bin/sh
project_dir=$(pwd)
echo ./*.c $CFLAGS -o $OUTPUT$(basename $project_dir) | xargs $CC

133
src/coreutils/wc/wc.c Normal file
View file

@ -0,0 +1,133 @@
#include <fcntl.h>
#include <stdio.h>
#include <errno.h>
#include <ctype.h>
#include <unistd.h>
#include <string.h>
#include "config.h"
/* cmd arguments l - lines c - bytes w - words */
unsigned int l_flag;
unsigned int c_flag;
unsigned int w_flag;
unsigned int t_flag;
unsigned int words;
unsigned int bytes;
unsigned int lines;
/* Total */
unsigned int twords;
unsigned int tbytes;
unsigned int tlines;
void count(const int fd) {
char buf[BUF_SIZE + 1];
off_t n = 0;
int in_word = 1;
while ((n = read(fd, buf, sizeof(buf))) > 0) {
bytes += n;
for (ssize_t i = 0; i < n; i++) {
if (buf[i] == '\n')
lines++;
if (isspace(buf[i]))
in_word = 1;
else {
if (in_word)
words++;
in_word = 0;
}
}
}
tbytes += bytes;
twords += words;
tlines += lines;
}
void print_count(const char *path, unsigned int plines, unsigned int pwords, unsigned int pbytes) {
if (l_flag)
printf("%7u ", plines);
if (w_flag)
printf(" %7u", pwords);
if (c_flag)
printf(" %7u", pbytes);
printf(" %s\n", path);
}
int main(int argc, char **argv) {
int opt;
while ((opt = getopt(argc, argv, "lcwt")) != -1) {
switch (opt) {
case 'l':
l_flag = 1;
break;
case 'c':
c_flag = 1;
break;
case 'w':
w_flag = 1;
break;
case 't':
t_flag = 1;
break;
default:
printf("wc [lcwt] [file1 file2...]\n\t-l Lines\n\t-c Bytes\n\t-w Words\n\t-t Don't print total\n");
return 0;
}
}
argv += optind;
argc -= optind;
if (!w_flag && !l_flag && !c_flag) {
w_flag = 1;
l_flag = 1;
c_flag = 1;
}
if (argc == 0) {
count(STDIN_FILENO);
print_count("", lines, words, bytes);
return 0;
}
for (int i = 0; i < argc; i++) {
if (argv[i][0] == '-') {
count(STDIN_FILENO);
print_count("-", lines, words, bytes);
}
else {
int fd = open(argv[i], O_RDONLY);
if (fd < 0) {
fprintf(stderr, "wc: %s: %s\n", argv[i], strerror(errno));
return 1;
}
count(fd);
print_count(argv[i], lines, words, bytes);
close(fd);
}
words = bytes = lines = 0;
}
if (!t_flag)
print_count("total", tlines, twords, tbytes);
return 0;
}

3
src/coreutils/whoami/build.sh Executable file
View file

@ -0,0 +1,3 @@
#!/bin/sh
project_dir=$(pwd)
echo ./*.c $CFLAGS -o $OUTPUT$(basename $project_dir) | xargs $CC

View file

@ -0,0 +1,18 @@
#include <sys/types.h>
#include <unistd.h>
#include <pwd.h>
#include <errno.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int main(void) {
struct passwd *pw = getpwuid(getuid());
if (!pw) {
fprintf(stderr, "whoami: %s\n", strerror(errno));
return 1;
}
puts(pw->pw_name);
return 0;
}

3
src/coreutils/yes/build.sh Executable file
View file

@ -0,0 +1,3 @@
#!/bin/sh
project_dir=$(pwd)
echo ./*.c $CFLAGS -o $OUTPUT$(basename $project_dir) | xargs $CC

24
src/coreutils/yes/yes.c Normal file
View file

@ -0,0 +1,24 @@
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
void print(const char *buf, ssize_t len) {
if (write(STDOUT_FILENO, buf, len) < 0)
exit(1);
}
int main(const int argc, const char **argv) {
if (argc == 1)
while (1)
print("y\n", 2);
while (1) {
for (ssize_t i = 1; i < argc; i++) {
print(argv[i], strlen(argv[i]));
print(" ", 1);
}
print("\n", 1);
}
}

3
src/editors/que/build.sh Executable file
View file

@ -0,0 +1,3 @@
#!/bin/sh
project_dir=$(pwd)
echo *.c $CFLAGS -o $OUTPUT$(basename $project_dir) | xargs $CC

637
src/editors/que/que.c Normal file
View file

@ -0,0 +1,637 @@
/* Safe variant of kilo editor */
/* Based on the web-tutorial and contain many edits */
#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
struct termios orig_termios;
struct winsize ws;
char *scr_buf;
size_t scr_buf_size;
struct row {
char *buf;
size_t len;
char *render;
size_t rlen;
};
struct row *row_s;
size_t row_size;
/* Cursors */
unsigned int curx;
unsigned int cury;
unsigned int renx;
unsigned int rowoff;
unsigned int coloff;
char *file_path;
enum {
FAILED_SAVE = 1,
SUCCESS_SAVE,
MARK
};
char status_type;
char modified_flag;
/* for mark */
char mark_flag;
unsigned int curx2;
unsigned int cury2;
/* Cleaners */
void bufFree(void) {
if (scr_buf != NULL)
free(scr_buf);
scr_buf = NULL;
scr_buf_size = 0;
}
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;
}
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 */
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;
}
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 */
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;
}
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;
}
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;
}
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);
}
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++;
}
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;
}
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");
}
}
void cmd(void) {
/* Execute internal cmds */
}
/* Terminal */
void DRawMode(void) {
if (tcsetattr(STDIN_FILENO, TCSAFLUSH, &orig_termios) < 0)
die(1, "tcsetattr");
}
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");
}
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--;
}
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);
else if (status_type == MARK)
ret = snprintf(info, sizeof(info), "Mark set at %ux %uy", curx, cury);
status_type = 0;
bufAppend(info, ret);
}
/* Keyboard */
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;
}
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;
}
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('f'):
cmd();
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();
}
}

3
src/findutils/grep/build.sh Executable file
View file

@ -0,0 +1,3 @@
#!/bin/sh
project_dir=$(pwd)
echo ./*.c $CFLAGS -o $OUTPUT$(basename $project_dir) | xargs $CC

64
src/findutils/grep/grep.c Normal file
View file

@ -0,0 +1,64 @@
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <unistd.h>
#include <regex.h>
typedef struct {
char *pattern;
regex_t rgex;
} PATTERN;
PATTERN *regexs;
size_t r_size;
int addpattern(char *str) {
if (regexs == NULL) {
regexs = malloc(sizeof(PATTERN));
if (regexs == NULL) {
fprintf(stderr, "grep: malloc failed\n");
return 1;
}
}
PATTERN *regexs_tmp = realloc(regexs, (r_size + 1) * sizeof(PATTERN));
if (regexs_tmp == NULL) {
free(regexs);
fprintf(stderr, "grep: realloc failed\n");
return 1;
}
regexs = regexs_tmp;
regexs[r_size].pattern = str;
r_size++;
return 0;
}
int main(int argc, char **argv) {
int opt;
while ((opt = getopt(argc, argv, "e:")) != -1) {
switch (opt) {
case 'e':
if (addpattern(optarg))
return 1;
break;
default:
printf("grep [e] [FILE]\n\t-e PTRN Pattern to match\n");
return 0;
}
}
argv += optind;
argc -= optind;
if (r_size == 0) {
fprintf(stderr, "grep: no patterns specified\n");
return 1;
}
free(regexs);
return 0;
}

Some files were not shown because too many files have changed in this diff Show more