sbase

suckless unix tools
git clone git://git.2f30.org/sbase.git
Log | Files | Refs | README | LICENSE

commit fbb80983ce607a54ccd9525772c24f9c9526fce6
parent 026e63c005683c0004e1a4307b08b4ce3177ccea
Author: Connor Lane Smith <cls@lubutu.com>
Date:   Tue May 24 13:00:30 +0100

add ln, util.a
Diffstat:
Makefile | 17+++++++++++------
config.mk | 2++
ln.1 | 22++++++++++++++++++++++
ln.c | 23+++++++++++++++++++++++
util.c | 22----------------------
util.h | 1+
util/enmasse.c | 38++++++++++++++++++++++++++++++++++++++
util/eprintf.c | 22++++++++++++++++++++++
8 files changed, 119 insertions(+), 28 deletions(-)
diff --git a/Makefile b/Makefile @@ -1,22 +1,27 @@ include config.mk -SRC = basename.c cat.c date.c echo.c false.c grep.c pwd.c rm.c sleep.c tee.c touch.c true.c wc.c -OBJ = $(SRC:.c=.o) util.o +LIB = util/enmasse.o util/eprintf.o +SRC = basename.c cat.c date.c echo.c false.c grep.c ln.c pwd.c rm.c sleep.c tee.c touch.c true.c wc.c +OBJ = $(SRC:.c=.o) $(LIB) BIN = $(SRC:.c=) MAN = $(SRC:.c=.1) all: $(BIN) $(OBJ): util.h -$(BIN): util.o +$(BIN): util.a .o: @echo CC -o $@ - @$(CC) -o $@ $< util.o $(LDFLAGS) + @$(CC) -o $@ $< util.a $(LDFLAGS) .c.o: @echo CC -c $< - @$(CC) -c $< $(CFLAGS) + @$(CC) -c -o $@ $< $(CFLAGS) + +util.a: $(LIB) + @echo AR rc $@ + @$(AR) rc $@ $(LIB) dist: clean @echo creating dist tarball @@ -28,4 +33,4 @@ dist: clean clean: @echo cleaning - @rm -f $(BIN) $(OBJ) + @rm -f $(BIN) $(OBJ) $(LIB) util.a diff --git a/config.mk b/config.mk @@ -4,6 +4,8 @@ VERSION = 0.0 #CC = cc CC = musl-gcc +AR = ar + CPPFLAGS = -D_BSD_SOURCE CFLAGS = -Os -ansi -Wall -pedantic $(CPPFLAGS) LDFLAGS = -s -static diff --git a/ln.1 b/ln.1 @@ -0,0 +1,22 @@ +.TH LN 1 sbase\-VERSION +.SH NAME +ln \- make links between files +.SH SYNOPSIS +.B ln +.RB [ \-s ] +.I file +.RI [ name ] +.P +.B ln +.RB [ \-s ] +.RI [ files ...] +.RI [ directory ] +.SH DESCRIPTION +.B ln +creates a hard link to a given file, with the given name. If no name is given +it is linked into the current directory. If multiple files are listed they will +be linked into the given directory. +.SH OPTIONS +.TP +.B \-s +create a symbolic link. diff --git a/ln.c b/ln.c @@ -0,0 +1,23 @@ +/* See LICENSE file for copyright and license details. */ +#include <stdbool.h> +#include <stdlib.h> +#include <unistd.h> +#include "util.h" + +int +main(int argc, char *argv[]) +{ + bool sflag = false; + char c; + + while((c = getopt(argc, argv, "s")) != -1) + switch(c) { + case 's': + sflag = true; + break; + default: + exit(EXIT_FAILURE); + } + enmasse(argc - optind, &argv[optind], sflag ? symlink : link); + return EXIT_SUCCESS; +} diff --git a/util.c b/util.c @@ -1,22 +0,0 @@ -/* See LICENSE file for copyright and license details. */ -#include <stdarg.h> -#include <stdio.h> -#include <stdlib.h> -#include <string.h> -#include "util.h" - -void -eprintf(const char *fmt, ...) -{ - va_list ap; - - va_start(ap, fmt); - vfprintf(stderr, fmt, ap); - va_end(ap); - - if(fmt[0] && fmt[strlen(fmt)-1] == ':') { - fputc(' ', stderr); - perror(NULL); - } - exit(EXIT_FAILURE); -} diff --git a/util.h b/util.h @@ -1,3 +1,4 @@ /* See LICENSE file for copyright and license details. */ +void enmasse(int, char **, int (*)(const char *, const char *)); void eprintf(const char *, ...); diff --git a/util/enmasse.c b/util/enmasse.c @@ -0,0 +1,38 @@ +/* See LICENSE file for copyright and license details. */ +#include <libgen.h> +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <unistd.h> +#include <sys/stat.h> +#include "../util.h" + +void +enmasse(int argc, char **argv, int (*fn)(const char *, const char *)) +{ + char *buf, *dir; + int i; + long size; + struct stat st; + + if(argc == 2 && !(stat(argv[1], &st) == 0 && S_ISDIR(st.st_mode))) { + if(fn(argv[0], argv[1]) != 0) + eprintf("%s:", argv[1]); + return; + } + else if(argc == 1) + dir = "."; + else + dir = argv[--argc]; + + if((size = pathconf(dir, _PC_PATH_MAX)) < 0) + size = BUFSIZ; + if(!(buf = malloc(size))) + eprintf("malloc:"); + for(i = 0; i < argc; i++) { + snprintf(buf, size, "%s/%s", dir, basename(argv[i])); + if(fn(argv[i], buf) != 0) + eprintf("%s:", buf); + } + free(buf); +} diff --git a/util/eprintf.c b/util/eprintf.c @@ -0,0 +1,22 @@ +/* See LICENSE file for copyright and license details. */ +#include <stdarg.h> +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include "../util.h" + +void +eprintf(const char *fmt, ...) +{ + va_list ap; + + va_start(ap, fmt); + vfprintf(stderr, fmt, ap); + va_end(ap); + + if(fmt[0] && fmt[strlen(fmt)-1] == ':') { + fputc(' ', stderr); + perror(NULL); + } + exit(EXIT_FAILURE); +}