diff options
| -rw-r--r-- | Makefile | 18 | ||||
| -rw-r--r-- | src/cat.c | 46 | ||||
| -rw-r--r-- | src/chmod.c | 32 | ||||
| -rw-r--r-- | src/chown.c | 36 | ||||
| -rw-r--r-- | src/echo.c | 9 | ||||
| -rw-r--r-- | src/false.c | 3 | ||||
| -rw-r--r-- | src/nologin.c | 6 | ||||
| -rw-r--r-- | src/pwd.c | 17 | ||||
| -rw-r--r-- | src/true.c | 3 |
9 files changed, 170 insertions, 0 deletions
diff --git a/Makefile b/Makefile new file mode 100644 index 0000000..7eac15c --- /dev/null +++ b/Makefile @@ -0,0 +1,18 @@ +SRCS = $(wildcard src/*.c) +BINS = $(patsubst src/%.c,bin/%,$(SRCS)) + +CFLAGS = +CC = gcc $(CFLAGS) + +all: build + +build: $(BINS) + +.SECONDEXPANSION: +$(BINS): $$(patsubst bin/%,src/%.c,$$@) + @mkdir -pv bin + $(CC) -o $@ $(patsubst bin/%,src/%.c,$@) + +clean: + rm -f $(BINS) + rmdir bin diff --git a/src/cat.c b/src/cat.c new file mode 100644 index 0000000..bf618cc --- /dev/null +++ b/src/cat.c @@ -0,0 +1,46 @@ +#include <errno.h> +#include <fcntl.h> +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <unistd.h> + +#define error(...) ({ \ + printf(__VA_ARGS__); \ + exit(EXIT_FAILURE); \ + }) + +static void cat(char *s) { + int fd = STDIN_FILENO; + ssize_t in, out; + char buf[1024]; + + if(strcmp(s, "-")) { + fd = open(s, O_RDONLY); + if(fd < 0) + error("Error opening %s: %s\n", s, strerror(errno)); + } + + for(;;) { + in = read(fd, buf, sizeof(buf)); + if(in < 0) + error("Error reading %s: %s\n", s, strerror(errno)); + out = write(STDOUT_FILENO, buf, in); + if(out < in) + error("Error writiing output: %s\n", strerror(errno)); + if(!in) + return; + } +} + +int main(int argc, char **argv) { + if(argc == 1) { + cat("-"); + return 0; + } + + while(argc-- > 1) + cat(*(++argv)); + + return 0; +} diff --git a/src/chmod.c b/src/chmod.c new file mode 100644 index 0000000..a16665f --- /dev/null +++ b/src/chmod.c @@ -0,0 +1,32 @@ +#include <errno.h> +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <sys/stat.h> + +int main(int argc, char **argv) { + int ret; + char **f; + mode_t mode; + + if(argc < 2) { + printf("Usage: %s <mode> <files>\n", argv[0]); + return EXIT_FAILURE; + } + + ret = sscanf(argv[1], "%o", &mode); + if(ret < 1) { + fprintf(stderr, "Invalid mode: %s\n", argv[1]); + return EXIT_FAILURE; + } + + f = &argv[2]; + argc -= 2; + + while(argc--) { + ret = chmod(*f, mode); + if(ret < 0) + fprintf(stderr, "Error changing mode on file %s: %s\n", *f, strerror(errno)); + f++; + } +} diff --git a/src/chown.c b/src/chown.c new file mode 100644 index 0000000..d4ba35a --- /dev/null +++ b/src/chown.c @@ -0,0 +1,36 @@ +#include <errno.h> +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <unistd.h> + +int main(int argc, char **argv) { + int ret; + char **f; + uid_t uid; + gid_t gid; + + if(argc < 2) { + printf("Usage: %s <uid>[:<gid>] <files>\n", argv[0]); + return EXIT_FAILURE; + } + + ret = sscanf(argv[1], "%d:%d", &uid, &gid); + if(ret < 1) { + fprintf(stderr, "Invalid owner: %s\n", argv[1]); + return EXIT_FAILURE; + } + + if(ret < 2) + gid = -1; + + f = &argv[2]; + argc -= 2; + + while(argc--) { + ret = chown(*f, uid, gid); + if(ret < 0) + fprintf(stderr, "Error changing ownership on file %s: %s\n", *f, strerror(errno)); + f++; + } +} diff --git a/src/echo.c b/src/echo.c new file mode 100644 index 0000000..df70cce --- /dev/null +++ b/src/echo.c @@ -0,0 +1,9 @@ +#include <stdio.h> + +int main(int argc, char **argv) { + argc--; + argv++; + + while(argc--) + printf("%s%c", *(argv++), argc ? ' ' : '\n'); +} diff --git a/src/false.c b/src/false.c new file mode 100644 index 0000000..80eeb5d --- /dev/null +++ b/src/false.c @@ -0,0 +1,3 @@ +int main(int argc, char **argv) { + return 1; +} diff --git a/src/nologin.c b/src/nologin.c new file mode 100644 index 0000000..2fd7093 --- /dev/null +++ b/src/nologin.c @@ -0,0 +1,6 @@ +#include <stdio.h> + +int main(int argc, char **argv) { + puts("This account is currently not available."); + return 1; +} diff --git a/src/pwd.c b/src/pwd.c new file mode 100644 index 0000000..b884933 --- /dev/null +++ b/src/pwd.c @@ -0,0 +1,17 @@ +#include <errno.h> +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <unistd.h> + +int main(int argc, char **argv) { + char buf[1024]; + + if(!getcwd(buf, sizeof(buf))) { + perror("Error getting current directory"); + return EXIT_FAILURE; + } + + puts(buf); + return 0; +} diff --git a/src/true.c b/src/true.c new file mode 100644 index 0000000..5c2fa9b --- /dev/null +++ b/src/true.c @@ -0,0 +1,3 @@ +int main(int argc, char **argv) { + return 0; +} |
