diff --git a/Makefile b/Makefile index e427c1e..2268441 100644 --- a/Makefile +++ b/Makefile @@ -10,26 +10,26 @@ PREFIX=/usr/local CFLAGS=-O3 -s -Wl,-z,noseparate-code,-z,nosectionheader -flto -Lbuild -lyac -build: build_dir lib cat false tail true +build: build_dir cat false tail true clean: build_dir rm -rf build/ -cat: build_dir +cat: build_dir lib cc $(CFLAGS) -o build/cat src/cat.c -false: build_dir +false: build_dir lib cc $(CFLAGS) -o build/false src/false.c -tail: build_dir +tail: build_dir lib cc $(CFLAGS) -o build/tail src/tail.c -true: build_dir +true: build_dir lib cc $(CFLAGS) -o build/true src/true.c lib: - cc -c -fPIC $(CFLAGS) -o build/yac.o src/yac.c - cc $(CFLAGS) -shared -o build/libyac.so build/yac.o + cc $(CFLAGS) -c -fPIC -o build/yac.o src/yac.c + cc -shared -o build/libyac.so build/yac.o build_dir: mkdir -p build diff --git a/src/tail.c b/src/tail.c new file mode 100644 index 0000000..d27829f --- /dev/null +++ b/src/tail.c @@ -0,0 +1,134 @@ +/* + * Copyright (c) 2023 Emma Tebibyte + * SPDX-License-Identifier: AGPL-3.0-or-later + * + * This file is part of YAC coreutils. + * + * YAC coreutils is free software: you can redistribute it and/or modify it + * under the terms of the GNU Affero General Public License as published by the + * Free Software Foundation, either version 3 of the License, or (at your + * option) any later version. + * + * YAC coreutils is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS + * FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License for more + * details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see https://www.gnu.org/licenses/. + */ + +#include +#include +#include +#include +#include + +#include "yac.h" + +void tail(FILE *file, bool c, bool f, long num) { + long offset; + if (c) { fseek(file, offset, SEEK_END); } + else { + for + } + +} + +int main(int argc, char *argv[]) { + bool c = false; + bool f = false; + bool n = false; + long num; + int opt; + int i; + + extern int optind; + while ((opt = getopt(argc, argv, "c:fn:")) != -1) { + switch (opt) { + /* + * From tail(1p): + * + * -c number The application shall ensure that the number option-argument + * is a decimal integer, optionally including a sign. The sign + * shall affect the location in the file, measured in bytes, to + * begin the copying: + * + * ┌─────┬────────────────────────────────────────┐ + * │Sign │ Copying Starts │ + * ├─────┼────────────────────────────────────────┤ + * │ + │ Relative to the beginning of the file. │ + * │ - │ Relative to the end of the file. │ + * │none │ Relative to the end of the file. │ + * └─────┴────────────────────────────────────────┘ + * The application shall ensure that if the sign of the number + * option-argument is '+', the number option-argument is a non- + * zero decimal integer. + * + * The origin for counting shall be 1; that is, -c +1 represents + * the first byte of the file, -c -1 the last. + * + * -f If the input file is a regular file or if the file operand + * specifies a FIFO, do not terminate after the last line of the + * input file has been copied, but read and copy further bytes + * from the input file when they become available. If no file + * operand is specified and standard input is a pipe or FIFO, + * the -f option shall be ignored. If the input file is not a + * FIFO, pipe, or regular file, it is unspecified whether or not + * the -f option shall be ignored. + * + * -n number This option shall be equivalent to -c number, except the + * starting location in the file shall be measured in lines + * instead of bytes. The origin for counting shall be 1; that + * is, -n +1 represents the first line of the file, -n -1 the + * last. + * + * If neither -c nor -n is specified, -n 10 shall be assumed. + */ + case 'c': + c = true; + num = (long)optarg; + break; + case 'f': + f = true; + case 'n': + n = true; + num = (long)optarg; + break; + default: + fprintf( + stderr, + "Usage: %s (-f) [-c characters] [-n lines] file...\n", + argv[0] + ); + return EX_USAGE; + } + } + + if (!n && !c) { + num = 10; + } else if (n && c) { + fprintf( + stderr, + "Usage: %s (-f) [-c characters] [-n lines] file...\n", + argv[0] + ); + return EX_USAGE; + } + + if (optind = argc) { + tail(stdin, c, f, num); + } + + FILE *file; + + for (i = optind; i < argc; i++) { + file = rfile(argv0, argv[i]); + if file != NULL { + tail(file, c, f, num); + if (file != stdin) { fclose(file); } + } + } + + return EX_OK; +}