commit 987ec1ef093584d7540a61262f90b7b1250b64bd
Author: sin <sin@2f30.org>
Date: Tue, 6 Aug 2013 12:16:27 +0100
Initial commit of ubase - the ugly/unportable base
Diffstat:
A | LICENSE | | | 21 | +++++++++++++++++++++ |
A | Makefile | | | 84 | +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ |
A | arg.h | | | 55 | +++++++++++++++++++++++++++++++++++++++++++++++++++++++ |
A | config.mk | | | 23 | +++++++++++++++++++++++ |
A | df.c | | | 69 | +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ |
A | linux/grabmntinfo.c | | | 31 | +++++++++++++++++++++++++++++++ |
A | openbsd/grabmntinfo.c | | | 29 | +++++++++++++++++++++++++++++ |
A | ubase.h | | | 7 | +++++++ |
A | util.h | | | 11 | +++++++++++ |
A | util/eprintf.c | | | 46 | ++++++++++++++++++++++++++++++++++++++++++++++ |
A | util/estrtol.c | | | 27 | +++++++++++++++++++++++++++ |
11 files changed, 403 insertions(+), 0 deletions(-)
diff --git a/LICENSE b/LICENSE
@@ -0,0 +1,21 @@
+MIT/X Consortium License
+
+© 2013 sin <sin@2f30.org>
+
+Permission is hereby granted, free of charge, to any person obtaining a
+copy of this software and associated documentation files (the "Software"),
+to deal in the Software without restriction, including without limitation
+the rights to use, copy, modify, merge, publish, distribute, sublicense,
+and/or sell copies of the Software, and to permit persons to whom the
+Software is furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+DEALINGS IN THE SOFTWARE.
diff --git a/Makefile b/Makefile
@@ -0,0 +1,84 @@
+include config.mk
+
+.POSIX:
+.SUFFIXES: .c .o
+
+HDR = util.h arg.h ubase.h
+LIB = \
+ $(OS)/grabmntinfo.o \
+ util/eprintf.o \
+ util/estrtol.o
+
+SRC = \
+ df.c
+
+OBJ = $(SRC:.c=.o) $(LIB)
+BIN = $(SRC:.c=)
+MAN = $(SRC:.c=.1)
+
+all: binlib
+
+binlib: util.a
+ $(MAKE) bin
+
+bin: $(BIN)
+
+$(OBJ): util.h config.mk
+
+.o:
+ @echo LD $@
+ @$(LD) -o $@ $< util.a $(LDFLAGS)
+
+.c.o:
+ @echo CC $<
+ @$(CC) -c -o $@ $< $(CFLAGS)
+
+util.a: $(LIB)
+ @echo AR $@
+ @$(AR) -r -c $@ $(LIB)
+ @ranlib $@
+
+install: all
+ @echo installing executables to $(DESTDIR)$(PREFIX)/bin
+ @mkdir -p $(DESTDIR)$(PREFIX)/bin
+ @cp -f $(BIN) $(DESTDIR)$(PREFIX)/bin
+ @cd $(DESTDIR)$(PREFIX)/bin && chmod 755 $(BIN)
+ @echo installing manual pages to $(DESTDIR)$(MANPREFIX)/man1
+ @mkdir -p $(DESTDIR)$(MANPREFIX)/man1
+ @cp -f $(MAN) $(DESTDIR)$(MANPREFIX)/man1
+ @cd $(DESTDIR)$(MANPREFIX)/man1 && chmod 644 $(MAN)
+
+uninstall:
+ @echo removing executables from $(DESTDIR)$(PREFIX)/bin
+ @cd $(DESTDIR)$(PREFIX)/bin && rm -f $(BIN)
+ @echo removing manual pages from $(DESTDIR)$(MANPREFIX)/man1
+ @cd $(DESTDIR)$(MANPREFIX)/man1 && rm -f $(MAN)
+
+dist: clean
+ @echo creating dist tarball
+ @mkdir -p ubase-$(VERSION)
+ @cp -r LICENSE Makefile config.mk $(SRC) $(MAN) util $(HDR) ubase-$(VERSION)
+ @tar -cf ubase-$(VERSION).tar ubase-$(VERSION)
+ @gzip ubase-$(VERSION).tar
+ @rm -rf ubase-$(VERSION)
+
+ubase-box: $(SRC) util.a
+ @echo creating box binary
+ @mkdir -p build
+ @cp $(HDR) build
+ @for f in $(SRC); do sed "s/^main(/`basename $$f .c`_&/" < $$f > build/$$f; done
+ @echo '#include <libgen.h>' > build/$@.c
+ @echo '#include <stdlib.h>' >> build/$@.c
+ @echo '#include <string.h>' >> build/$@.c
+ @echo '#include "util.h"' >> build/$@.c
+ @for f in $(SRC); do echo "int `basename $$f .c`_main(int, char **);" >> build/$@.c; done
+ @echo 'int main(int argc, char *argv[]) { char *s = basename(argv[0]); if(0) ;' >> build/$@.c
+ @for f in $(SRC); do echo "else if(!strcmp(s, \"`basename $$f .c`\")) `basename $$f .c`_main(argc, argv);" >> build/$@.c; done
+ @printf 'else eprintf("%%s: unknown program\\n", s); return EXIT_SUCCESS; }\n' >> build/$@.c
+ @echo LD $@
+ @$(LD) -o $@ build/*.c util.a $(CFLAGS) $(LDFLAGS)
+ @rm -r build
+
+clean:
+ @echo cleaning
+ @rm -f $(BIN) $(OBJ) $(LIB) util.a ubase-box
diff --git a/arg.h b/arg.h
@@ -0,0 +1,55 @@
+/*
+ * Copy me if you can.
+ * by 20h
+ */
+
+#ifndef __ARG_H__
+#define __ARG_H__
+
+extern char *argv0;
+
+#define USED(x) ((void)(x))
+
+/* use main(int argc, char *argv[]) */
+#define ARGBEGIN for (argv0 = *argv, argv++, argc--;\
+ argv[0] && argv[0][1]\
+ && argv[0][0] == '-';\
+ argc--, argv++) {\
+ char _argc;\
+ char **_argv;\
+ int brk;\
+ if (argv[0][1] == '-' && argv[0][2] == '\0') {\
+ argv++;\
+ argc--;\
+ break;\
+ }\
+ for (brk = 0, argv[0]++, _argv = argv;\
+ argv[0][0] && !brk;\
+ argv[0]++) {\
+ if (_argv != argv)\
+ break;\
+ _argc = argv[0][0];\
+ switch (_argc)
+
+#define ARGEND }\
+ USED(_argc);\
+ }\
+ USED(argv);\
+ USED(argc);
+
+#define ARGC() _argc
+
+#define EARGF(x) ((argv[0][1] == '\0' && argv[1] == NULL)?\
+ ((x), abort(), (char *)0) :\
+ (brk = 1, (argv[0][1] != '\0')?\
+ (&argv[0][1]) :\
+ (argc--, argv++, argv[0])))
+
+#define ARGF() ((argv[0][1] == '\0' && argv[1] == NULL)?\
+ (char *)0 :\
+ (brk = 1, (argv[0][1] != '\0')?\
+ (&argv[0][1]) :\
+ (argc--, argv++, argv[0])))
+
+#endif
+
diff --git a/config.mk b/config.mk
@@ -0,0 +1,23 @@
+# ubase version
+VERSION = 0.0
+
+# paths
+PREFIX = /usr/local
+MANPREFIX = $(PREFIX)/share/man
+
+# OS to build against
+OS = linux
+#OS = openbsd
+
+#CC = gcc
+#CC = musl-gcc
+LD = $(CC)
+CPPFLAGS = -D_BSD_SOURCE -D_GNU_SOURCE
+CFLAGS = -g -ansi -Wall -Wno-long-long -pedantic $(CPPFLAGS)
+LDFLAGS = -g
+
+#CC = tcc
+#LD = $(CC)
+#CPPFLAGS = -D_POSIX_C_SOURCE=200112L
+#CFLAGS = -Os -Wall $(CPPFLAGS)
+#LDFLAGS =
diff --git a/df.c b/df.c
@@ -0,0 +1,69 @@
+/* See LICENSE file for copyright and license details. */
+#include <sys/statvfs.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include "ubase.h"
+#include "util.h"
+
+static void mnt_show(const char *fsname, const char *dir);
+
+static void
+usage(void)
+{
+ eprintf("usage: %s\n", argv0);
+}
+
+int
+main(int argc, char *argv[])
+{
+ struct mntinfo *minfo = NULL;
+ int siz, i;
+
+ ARGBEGIN {
+ case 'a':
+ break;
+ case 's':
+ case 'h':
+ case 'i':
+ eprintf("not implemented\n");
+ default:
+ usage();
+ } ARGEND;
+
+ printf("Filesystem 512-blocks Used Avail Capacity Mounted on\n");
+ siz = grabmntinfo(&minfo);
+ if (!siz)
+ eprintf("grabmntinfo:");
+
+ for (i = 0; i < siz; i++)
+ mnt_show(minfo[i].fsname, minfo[i].mntdir);
+ free(minfo);
+
+ return 0;
+}
+
+static void
+mnt_show(const char *fsname, const char *dir)
+{
+ struct statvfs s;
+ unsigned long long total, used, avail;
+ int capacity = 0;
+ int bs;
+
+ statvfs(dir, &s);
+
+ bs = s.f_frsize / 512;
+ total = s.f_blocks * bs;
+ avail = s.f_bfree * bs;
+ used = total - avail;
+
+ if (used + avail) {
+ capacity = (used * 100) / (used + avail);
+ if (used * 100 != capacity * (used + avail))
+ capacity++;
+ }
+
+ printf("%-12s %9llu %9llu %9llu %7d%% %s\n",
+ fsname, total, used, avail, capacity,
+ dir);
+}
diff --git a/linux/grabmntinfo.c b/linux/grabmntinfo.c
@@ -0,0 +1,31 @@
+/* See LICENSE file for copyright and license details. */
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <mntent.h>
+#include "../ubase.h"
+#include "../util.h"
+
+int
+grabmntinfo(struct mntinfo **minfo)
+{
+ struct mntent *me;
+ struct mntinfo *mi = NULL;
+ int siz = 0;
+ FILE *fp;
+
+ fp = setmntent("/proc/mounts", "r");
+ if (!fp)
+ eprintf("setmntent:");
+ while ((me = getmntent(fp))) {
+ mi = realloc(mi, (siz + 1) * sizeof(*mi));
+ if (!mi)
+ eprintf("realloc:");
+ mi[siz].fsname = strdup(me->mnt_fsname);
+ mi[siz].mntdir = strdup(me->mnt_dir);
+ siz++;
+ }
+ endmntent(fp);
+ *minfo = mi;
+ return siz;
+}
diff --git a/openbsd/grabmntinfo.c b/openbsd/grabmntinfo.c
@@ -0,0 +1,29 @@
+/* See LICENSE file for copyright and license details. */
+#include <sys/param.h>
+#include <sys/mount.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include "../ubase.h"
+#include "../util.h"
+
+int
+grabmntinfo(struct mntinfo **minfo)
+{
+ int siz, i;
+ struct statfs *mntbuf;
+ struct mntinfo *mi;
+
+ siz = getmntinfo(&mntbuf, MNT_WAIT);
+ if (!siz)
+ eprintf("getmntinfo:");
+ mi = malloc(siz * sizeof(*mi));
+ if (!mi)
+ eprintf("malloc:");
+ for (i = 0; i < siz; i++) {
+ mi[i].fsname = strdup(mntbuf[i].f_mntfromname);
+ mi[i].mntdir = strdup(mntbuf[i].f_mntonname);
+ }
+ *minfo = mi;
+ return siz;
+}
diff --git a/ubase.h b/ubase.h
@@ -0,0 +1,7 @@
+/* See LICENSE file for copyright and license details. */
+struct mntinfo {
+ const char *fsname;
+ const char *mntdir;
+};
+
+int grabmntinfo(struct mntinfo **minfo);
diff --git a/util.h b/util.h
@@ -0,0 +1,11 @@
+/* See LICENSE file for copyright and license details. */
+#include "arg.h"
+
+#define UTF8_POINT(c) (((c) & 0xc0) != 0x80)
+#define LEN(x) (sizeof (x) / sizeof *(x))
+
+extern char *argv0;
+
+void eprintf(const char *, ...);
+void enprintf(int, const char *, ...);
+long estrtol(const char *, int);
diff --git a/util/eprintf.c b/util/eprintf.c
@@ -0,0 +1,46 @@
+/* See LICENSE file for copyright and license details. */
+#include <stdarg.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include "../util.h"
+
+char *argv0;
+
+static void venprintf(int, const char *, va_list);
+
+void
+eprintf(const char *fmt, ...)
+{
+ va_list ap;
+
+ va_start(ap, fmt);
+ venprintf(EXIT_FAILURE, fmt, ap);
+ va_end(ap);
+}
+
+void
+enprintf(int status, const char *fmt, ...)
+{
+ va_list ap;
+
+ va_start(ap, fmt);
+ venprintf(status, fmt, ap);
+ va_end(ap);
+}
+
+void
+venprintf(int status, const char *fmt, va_list ap)
+{
+ /*fprintf(stderr, "%s: ", argv0);*/
+
+ vfprintf(stderr, fmt, ap);
+
+ if(fmt[0] && fmt[strlen(fmt)-1] == ':') {
+ fputc(' ', stderr);
+ perror(NULL);
+ }
+
+ exit(status);
+}
diff --git a/util/estrtol.c b/util/estrtol.c
@@ -0,0 +1,27 @@
+/* See LICENSE file for copyright and license details. */
+#include <errno.h>
+#include <stdio.h>
+#include <stdlib.h>
+
+#include "../util.h"
+
+long
+estrtol(const char *s, int base)
+{
+ char *end;
+ long n;
+
+ errno = 0;
+ n = strtol(s, &end, base);
+ if(*end != '\0') {
+ if(base == 0)
+ eprintf("%s: not an integer\n", s);
+ else
+ eprintf("%s: not a base %d integer\n", s, base);
+ }
+ if(errno != 0)
+ eprintf("%s:", s);
+
+ return n;
+}
+