commit fbb80983ce607a54ccd9525772c24f9c9526fce6
parent 026e63c005683c0004e1a4307b08b4ce3177ccea
Author: Connor Lane Smith <cls@lubutu.com>
Date: Tue, 24 May 2011 13:00:30 +0100
add ln, util.a
Diffstat:
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);
+}