ubase

suckless linux base utils
git clone git://git.2f30.org/ubase.git
Log | Files | Refs | README | LICENSE

commit 987ec1ef093584d7540a61262f90b7b1250b64bd
Author: sin <sin@2f30.org>
Date:   Tue Aug  6 12:16:27 +0100

Initial commit of ubase - the ugly/unportable base

Diffstat:
LICENSE | 21+++++++++++++++++++++
Makefile | 84+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
arg.h | 55+++++++++++++++++++++++++++++++++++++++++++++++++++++++
config.mk | 23+++++++++++++++++++++++
df.c | 69+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
linux/grabmntinfo.c | 31+++++++++++++++++++++++++++++++
openbsd/grabmntinfo.c | 29+++++++++++++++++++++++++++++
ubase.h | 7+++++++
util.h | 11+++++++++++
util/eprintf.c | 46++++++++++++++++++++++++++++++++++++++++++++++
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; +} +