first commit
This commit is contained in:
commit
21be7fd279
156 changed files with 6939 additions and 0 deletions
3
src/console-tools/clear/build.sh
Executable file
3
src/console-tools/clear/build.sh
Executable file
|
@ -0,0 +1,3 @@
|
|||
#!/bin/sh
|
||||
project_dir=$(pwd)
|
||||
echo ./*.c $CFLAGS -o $OUTPUT$(basename $project_dir) | xargs $CC
|
5
src/console-tools/clear/clear.c
Normal file
5
src/console-tools/clear/clear.c
Normal file
|
@ -0,0 +1,5 @@
|
|||
#include <unistd.h>
|
||||
|
||||
int main(void) {
|
||||
return write(1, "\033[H\033[J", 6) != 6;
|
||||
}
|
3
src/console-tools/reset/build.sh
Executable file
3
src/console-tools/reset/build.sh
Executable file
|
@ -0,0 +1,3 @@
|
|||
#!/bin/sh
|
||||
project_dir=$(pwd)
|
||||
echo ./*.c $CFLAGS -o $OUTPUT$(basename $project_dir) | xargs $CC
|
5
src/console-tools/reset/reset.c
Normal file
5
src/console-tools/reset/reset.c
Normal 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;
|
||||
}
|
57
src/coreutils/bdname/bdname.c
Normal file
57
src/coreutils/bdname/bdname.c
Normal 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
3
src/coreutils/bdname/build.sh
Executable 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
3
src/coreutils/cat/build.sh
Executable 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
54
src/coreutils/cat/cat.c
Normal 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
3
src/coreutils/chgrp/build.sh
Executable file
|
@ -0,0 +1,3 @@
|
|||
#!/bin/sh
|
||||
project_dir=$(pwd)
|
||||
echo ./*.c $CFLAGS -o $OUTPUT$(basename $project_dir) | xargs $CC
|
92
src/coreutils/chgrp/chgrp.c
Normal file
92
src/coreutils/chgrp/chgrp.c
Normal 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
3
src/coreutils/chmod/build.sh
Executable 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
103
src/coreutils/chmod/chmod.c
Normal 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
3
src/coreutils/chown/build.sh
Executable 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
131
src/coreutils/chown/chown.c
Normal 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
3
src/coreutils/chroot/build.sh
Executable file
|
@ -0,0 +1,3 @@
|
|||
#!/bin/sh
|
||||
project_dir=$(pwd)
|
||||
echo ./*.c $CFLAGS -o $OUTPUT$(basename $project_dir) | xargs $CC
|
29
src/coreutils/chroot/chroot.c
Normal file
29
src/coreutils/chroot/chroot.c
Normal 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
3
src/coreutils/cmp/build.sh
Executable 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
126
src/coreutils/cmp/cmp.c
Normal 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
3
src/coreutils/cp/build.sh
Executable 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
213
src/coreutils/cp/cp.c
Normal 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
3
src/coreutils/date/build.sh
Executable 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
109
src/coreutils/date/date.c
Normal 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
3
src/coreutils/dd/build.sh
Executable 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
249
src/coreutils/dd/dd.c
Normal 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
3
src/coreutils/df/build.sh
Executable 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
95
src/coreutils/df/df.c
Normal 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
3
src/coreutils/du/build.sh
Executable 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
111
src/coreutils/du/du.c
Normal 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
3
src/coreutils/echo/build.sh
Executable 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
94
src/coreutils/echo/echo.c
Normal 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
3
src/coreutils/env/build.sh
vendored
Executable 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
33
src/coreutils/env/env.c
vendored
Normal 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
3
src/coreutils/false/build.sh
Executable file
|
@ -0,0 +1,3 @@
|
|||
#!/bin/sh
|
||||
project_dir=$(pwd)
|
||||
echo ./*.c $CFLAGS -o $OUTPUT$(basename $project_dir) | xargs $CC
|
3
src/coreutils/false/false.c
Normal file
3
src/coreutils/false/false.c
Normal file
|
@ -0,0 +1,3 @@
|
|||
int main(void) {
|
||||
return 1;
|
||||
}
|
3
src/coreutils/head/build.sh
Executable file
3
src/coreutils/head/build.sh
Executable 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
95
src/coreutils/head/head.c
Normal 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
3
src/coreutils/id/build.sh
Executable 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
130
src/coreutils/id/id.c
Normal 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
3
src/coreutils/ln/build.sh
Executable 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
76
src/coreutils/ln/ln.c
Normal 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
3
src/coreutils/ls/build.sh
Executable 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
508
src/coreutils/ls/ls.c
Normal 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
3
src/coreutils/mkdir/build.sh
Executable file
|
@ -0,0 +1,3 @@
|
|||
#!/bin/sh
|
||||
project_dir=$(pwd)
|
||||
echo ./*.c $CFLAGS -o $OUTPUT$(basename $project_dir) | xargs $CC
|
85
src/coreutils/mkdir/mkdir.c
Normal file
85
src/coreutils/mkdir/mkdir.c
Normal 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
3
src/coreutils/mknod/build.sh
Executable file
|
@ -0,0 +1,3 @@
|
|||
#!/bin/sh
|
||||
project_dir=$(pwd)
|
||||
echo ./*.c $CFLAGS -o $OUTPUT$(basename $project_dir) | xargs $CC
|
81
src/coreutils/mknod/mknod.c
Normal file
81
src/coreutils/mknod/mknod.c
Normal 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
3
src/coreutils/mktemp/build.sh
Executable file
|
@ -0,0 +1,3 @@
|
|||
#!/bin/sh
|
||||
project_dir=$(pwd)
|
||||
echo ./*.c $CFLAGS -o $OUTPUT$(basename $project_dir) | xargs $CC
|
98
src/coreutils/mktemp/mktemp.c
Normal file
98
src/coreutils/mktemp/mktemp.c
Normal 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
3
src/coreutils/mv/build.sh
Executable 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
62
src/coreutils/mv/mv.c
Normal 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
3
src/coreutils/nice/build.sh
Executable 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
43
src/coreutils/nice/nice.c
Normal 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
3
src/coreutils/nohup/build.sh
Executable file
|
@ -0,0 +1,3 @@
|
|||
#!/bin/sh
|
||||
project_dir=$(pwd)
|
||||
echo ./*.c $CFLAGS -o $OUTPUT$(basename $project_dir) | xargs $CC
|
42
src/coreutils/nohup/nohup.c
Normal file
42
src/coreutils/nohup/nohup.c
Normal 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
3
src/coreutils/nproc/build.sh
Executable file
|
@ -0,0 +1,3 @@
|
|||
#!/bin/sh
|
||||
project_dir=$(pwd)
|
||||
echo ./*.c $CFLAGS -o $OUTPUT$(basename $project_dir) | xargs $CC
|
11
src/coreutils/nproc/nproc.c
Normal file
11
src/coreutils/nproc/nproc.c
Normal 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;
|
||||
}
|
3
src/coreutils/printenv/build.sh
Executable file
3
src/coreutils/printenv/build.sh
Executable file
|
@ -0,0 +1,3 @@
|
|||
#!/bin/sh
|
||||
project_dir=$(pwd)
|
||||
echo ./*.c $CFLAGS -o $OUTPUT$(basename $project_dir) | xargs $CC
|
40
src/coreutils/printenv/printenv.c
Normal file
40
src/coreutils/printenv/printenv.c
Normal 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
3
src/coreutils/pwd/build.sh
Executable 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
19
src/coreutils/pwd/pwd.c
Normal 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;
|
||||
}
|
3
src/coreutils/readlink/build.sh
Executable file
3
src/coreutils/readlink/build.sh
Executable file
|
@ -0,0 +1,3 @@
|
|||
#!/bin/sh
|
||||
project_dir=$(pwd)
|
||||
echo ./*.c $CFLAGS -o $OUTPUT$(basename $project_dir) | xargs $CC
|
48
src/coreutils/readlink/readlink.c
Normal file
48
src/coreutils/readlink/readlink.c
Normal 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
3
src/coreutils/renice/build.sh
Executable file
|
@ -0,0 +1,3 @@
|
|||
#!/bin/sh
|
||||
project_dir=$(pwd)
|
||||
echo ./*.c $CFLAGS -o $OUTPUT$(basename $project_dir) | xargs $CC
|
73
src/coreutils/renice/renice.c
Normal file
73
src/coreutils/renice/renice.c
Normal 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
3
src/coreutils/rm/build.sh
Executable 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
112
src/coreutils/rm/rm.c
Normal 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
3
src/coreutils/seq/build.sh
Executable 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
58
src/coreutils/seq/seq.c
Normal 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
3
src/coreutils/setsid/build.sh
Executable file
|
@ -0,0 +1,3 @@
|
|||
#!/bin/sh
|
||||
project_dir=$(pwd)
|
||||
echo ./*.c $CFLAGS -o $OUTPUT$(basename $project_dir) | xargs $CC
|
21
src/coreutils/setsid/setsid.c
Normal file
21
src/coreutils/setsid/setsid.c
Normal 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
3
src/coreutils/shred/build.sh
Executable 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
113
src/coreutils/shred/shred.c
Normal 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
3
src/coreutils/sleep/build.sh
Executable file
|
@ -0,0 +1,3 @@
|
|||
#!/bin/sh
|
||||
project_dir=$(pwd)
|
||||
echo ./*.c $CFLAGS -o $OUTPUT$(basename $project_dir) | xargs $CC
|
29
src/coreutils/sleep/sleep.c
Normal file
29
src/coreutils/sleep/sleep.c
Normal 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
3
src/coreutils/split/build.sh
Executable 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
119
src/coreutils/split/split.c
Normal 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
3
src/coreutils/sync/build.sh
Executable file
|
@ -0,0 +1,3 @@
|
|||
#!/bin/sh
|
||||
project_dir=$(pwd)
|
||||
echo ./*.c $CFLAGS -o $OUTPUT$(basename $project_dir) | xargs $CC
|
6
src/coreutils/sync/sync.c
Normal file
6
src/coreutils/sync/sync.c
Normal file
|
@ -0,0 +1,6 @@
|
|||
#include <unistd.h>
|
||||
|
||||
int main(void) {
|
||||
sync();
|
||||
return 0;
|
||||
}
|
3
src/coreutils/tee/build.sh
Executable file
3
src/coreutils/tee/build.sh
Executable 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
61
src/coreutils/tee/tee.c
Normal 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
3
src/coreutils/time/build.sh
Executable 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
56
src/coreutils/time/time.c
Normal 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
3
src/coreutils/touch/build.sh
Executable 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
147
src/coreutils/touch/touch.c
Normal 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
3
src/coreutils/true/build.sh
Executable file
|
@ -0,0 +1,3 @@
|
|||
#!/bin/sh
|
||||
project_dir=$(pwd)
|
||||
echo ./*.c $CFLAGS -o $OUTPUT$(basename $project_dir) | xargs $CC
|
3
src/coreutils/true/true.c
Normal file
3
src/coreutils/true/true.c
Normal file
|
@ -0,0 +1,3 @@
|
|||
int main(void) {
|
||||
return 0;
|
||||
}
|
3
src/coreutils/tty/build.sh
Executable file
3
src/coreutils/tty/build.sh
Executable 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
13
src/coreutils/tty/tty.c
Normal 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
3
src/coreutils/uname/build.sh
Executable 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
132
src/coreutils/uname/uname.c
Normal 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
3
src/coreutils/wc/build.sh
Executable 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
133
src/coreutils/wc/wc.c
Normal 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
3
src/coreutils/whoami/build.sh
Executable file
|
@ -0,0 +1,3 @@
|
|||
#!/bin/sh
|
||||
project_dir=$(pwd)
|
||||
echo ./*.c $CFLAGS -o $OUTPUT$(basename $project_dir) | xargs $CC
|
18
src/coreutils/whoami/whoami.c
Normal file
18
src/coreutils/whoami/whoami.c
Normal 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
3
src/coreutils/yes/build.sh
Executable 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
24
src/coreutils/yes/yes.c
Normal 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
3
src/editors/que/build.sh
Executable 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
637
src/editors/que/que.c
Normal 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
3
src/findutils/grep/build.sh
Executable 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
64
src/findutils/grep/grep.c
Normal 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
Loading…
Add table
Add a link
Reference in a new issue