noice

small file browser
git clone git://git.2f30.org/noice
Log | Files | Refs | README | LICENSE

commit 50592339bf450037972b85777d1c524e35545aa8
parent 47d659c5fc930f0815c2bf5a24b3c2228b13695e
Author: sin <sin@2f30.org>
Date:   Fri,  2 Aug 2019 15:43:07 +0100

Implement nopen(1)

Diffstat:
MMakefile | 48++++++++++++++++++++++++++++--------------------
Dconfig.def.h | 102-------------------------------------------------------------------------------
Mnoice.1 | 24++++++++----------------
Mnoice.c | 113++++---------------------------------------------------------------------------
Anoiceconf.def.h | 93+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Anopen.1 | 31+++++++++++++++++++++++++++++++
Anopen.c | 95+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Anopenconf.def.h | 9+++++++++
Aspawn.c | 43+++++++++++++++++++++++++++++++++++++++++++
Mstrverscmp.c | 2++
Mutil.h | 21+++++++++++++--------
11 files changed, 327 insertions(+), 254 deletions(-)

diff --git a/Makefile b/Makefile @@ -1,45 +1,53 @@ VERSION = 0.8 - PREFIX = /usr/local MANPREFIX = $(PREFIX)/man #CPPFLAGS = -DDEBUG #CFLAGS = -g -LDLIBS = -lcurses -DISTFILES = noice.c strlcat.c strlcpy.c strverscmp.c util.h config.def.h\ - noice.1 Makefile README LICENSE -OBJ = noice.o strlcat.o strlcpy.o strverscmp.o -BIN = noice +NOICELDLIBS = -lcurses +NOPENLDLIBS = +NOICEOBJ = noice.o spawn.o strlcat.o strlcpy.o strverscmp.o +NOPENOBJ = nopen.o spawn.o +BIN = noice nopen +MAN = noice.1 nopen.1 all: $(BIN) -$(BIN): $(OBJ) - $(CC) $(CFLAGS) -o $@ $(OBJ) $(LDFLAGS) $(LDLIBS) +noice: $(NOICEOBJ) + $(CC) $(CFLAGS) -o $@ $(NOICEOBJ) $(LDFLAGS) $(NOICELDLIBS) + +nopen: $(NOPENOBJ) + $(CC) $(CFLAGS) -o $@ $(NOPENOBJ) $(LDFLAGS) $(NOPENLDLIBS) -noice.o: util.h config.h +noice.o: noiceconf.h util.h +nopen.o: nopenconf.h util.h +spawn.o: util.h strlcat.o: util.h strlcpy.o: util.h +strverscmp.o: util.h + +noiceconf.h: + cp noiceconf.def.h $@ -config.h: - cp config.def.h $@ +nopenconf.h: + cp nopenconf.def.h $@ install: all mkdir -p $(DESTDIR)$(PREFIX)/bin cp -f $(BIN) $(DESTDIR)$(PREFIX)/bin mkdir -p $(DESTDIR)$(MANPREFIX)/man1 - cp -f $(BIN).1 $(DESTDIR)$(MANPREFIX)/man1 + cp -f $(MAN) $(DESTDIR)$(MANPREFIX)/man1 uninstall: - rm -f $(DESTDIR)$(PREFIX)/bin/$(BIN) - rm -f $(DESTDIR)$(MANPREFIX)/man1/$(BIN).1 + cd $(DESTDIR)$(PREFIX)/bin && rm -f $(BIN) + cd $(DESTDIR)$(MANPREFIX)/man1 && rm -f $(MAN) -dist: +dist: clean mkdir -p noice-$(VERSION) - cp $(DISTFILES) noice-$(VERSION) - tar -cf noice-$(VERSION).tar noice-$(VERSION) - gzip noice-$(VERSION).tar - rm -rf noice-$(VERSION) + cp `find . -maxdepth 1 -type f` noice-$(VERSION) + tar -c noice-$(VERSION) | gzip > noice-$(VERSION).tar.gz clean: - rm -f $(BIN) $(OBJ) noice-$(VERSION).tar.gz + rm -f $(BIN) $(NOICEOBJ) $(NOPENOBJ) noice-$(VERSION).tar.gz + rm -rf noice-$(VERSION) diff --git a/config.def.h b/config.def.h @@ -1,102 +0,0 @@ -/* See LICENSE file for copyright and license details. */ -#define CWD "cwd: " -#define CURSR " > " -#define EMPTY " " - -int dirorder = 0; /* Set to 1 to sort by directory first */ -int mtimeorder = 0; /* Set to 1 to sort by time modified */ -int icaseorder = 0; /* Set to 1 to sort by ignoring case */ -int versorder = 0; /* Set to 1 to sort by version number */ -int idletimeout = 0; /* Screensaver timeout in seconds, 0 to disable */ -int showhidden = 0; /* Set to 1 to show hidden files by default */ -int usecolor = 0; /* Set to 1 to enable color attributes */ -char *idlecmd = "rain"; /* The screensaver program */ - -/* See curs_attr(3) for valid video attributes */ -#define CURSR_ATTR A_NORMAL -#define DIR_ATTR A_NORMAL | COLOR_PAIR(4) -#define LINK_ATTR A_NORMAL | COLOR_PAIR(6) -#define SOCK_ATTR A_NORMAL | COLOR_PAIR(1) -#define FIFO_ATTR A_NORMAL | COLOR_PAIR(5) -#define EXEC_ATTR A_NORMAL | COLOR_PAIR(2) - -/* Colors to use with COLOR_PAIR(n) as attributes */ -struct cpair pairs[] = { - { .fg = 0, .bg = 0 }, - /* pairs start at 1 */ - { COLOR_RED, -1 }, - { COLOR_GREEN, -1 }, - { COLOR_YELLOW, -1 }, - { COLOR_BLUE, -1 }, - { COLOR_MAGENTA, -1 }, - { COLOR_CYAN, -1 }, -}; - -struct assoc assocs[] = { - { .regex = "\\.(avi|mp4|mkv|mp3|ogg|flac|mov)$", .file = "mpv", .argv = { "mpv", "{}", NULL } }, - { .regex = "\\.(png|jpg|gif)$", .file = "sxiv", .argv = { "sxiv", "{}", NULL} }, - { .regex = "\\.(html|svg)$", .file = "firefox", .argv = { "firefox", "{}", NULL } }, - { .regex = "\\.pdf$", .file = "mupdf", .argv = { "mupdf", "{}", NULL} }, - { .regex = "\\.sh$", .file = "sh", .argv = { "sh", "{}", NULL} }, - { .regex = ".", .file = "less", .argv = { "less", "{}", NULL } }, -}; - -struct key bindings[] = { - /* Quit */ - { 'q', SEL_QUIT }, - /* Back */ - { KEY_BACKSPACE, SEL_BACK }, - { KEY_LEFT, SEL_BACK }, - { 'h', SEL_BACK }, - { CONTROL('H'), SEL_BACK }, - /* Inside */ - { KEY_ENTER, SEL_GOIN }, - { '\r', SEL_GOIN }, - { KEY_RIGHT, SEL_GOIN }, - { 'l', SEL_GOIN }, - /* Filter */ - { '/', SEL_FLTR }, - { '&', SEL_FLTR }, - /* Next */ - { 'j', SEL_NEXT }, - { KEY_DOWN, SEL_NEXT }, - { CONTROL('N'), SEL_NEXT }, - /* Previous */ - { 'k', SEL_PREV }, - { KEY_UP, SEL_PREV }, - { CONTROL('P'), SEL_PREV }, - /* Page down */ - { KEY_NPAGE, SEL_PGDN }, - { CONTROL('D'), SEL_PGDN }, - /* Page up */ - { KEY_PPAGE, SEL_PGUP }, - { CONTROL('U'), SEL_PGUP }, - /* Home */ - { KEY_HOME, SEL_HOME }, - { META('<'), SEL_HOME }, - { '^', SEL_HOME }, - /* End */ - { KEY_END, SEL_END }, - { META('>'), SEL_END }, - { '$', SEL_END }, - /* Change dir */ - { 'c', SEL_CD }, - { '~', SEL_CDHOME }, - /* Toggle hide .dot files */ - { '.', SEL_TOGGLEDOT }, - /* Toggle sort by directory first */ - { 'd', SEL_DSORT }, - /* Toggle sort by time */ - { 't', SEL_MTIME }, - /* Toggle case sensitivity */ - { 'i', SEL_ICASE }, - /* Toggle sort by version number */ - { 'v', SEL_VERS }, - { CONTROL('L'), SEL_REDRAW }, - /* Run command */ - { 'z', SEL_RUN, "top" }, - { '!', SEL_RUN, "sh", "SHELL" }, - /* Run command with argument */ - { 'e', SEL_RUNARG, "vi", "EDITOR" }, - { 'p', SEL_RUNARG, "less", "PAGER" }, -}; diff --git a/noice.1 b/noice.1 @@ -1,4 +1,4 @@ -.Dd March 31, 2019 +.Dd August 2, 2019 .Dt NOICE 1 .Os .Sh NAME @@ -84,23 +84,13 @@ directory you came out of. .Sh CONFIGURATION .Nm is configured by modifying -.Pa config.h +.Pa noiceconf.h and recompiling the code. .Pp -The file associations are specified by regexes -matching on the currently selected filename. -If a match is found the associated program is executed -with the filename passed in as the argument. -If no match is found the program -.Xr less 1 -is invoked. -This is useful for editing text files as one can use the -.Ic v -command in -.Xr less 1 -to edit the file using the -.Ev EDITOR -environment variable. +.Nm +invokes +.Xr nopen 1 +to open a file in the user's preferred application. .Sh FILTERS Filters allow you to use regexes to display only the matched entries in the current directory view. @@ -131,6 +121,8 @@ commands respectively. If you are using .Xr urxvt 1 you might have to set backspace key to DEC. +.Sh SEE ALSO +.Xr nopen 1 .Sh AUTHORS .An Lazaros Koromilas Aq Mt lostd@2f30.org , .An Dimitris Papastamos Aq Mt sin@2f30.org . diff --git a/noice.c b/noice.c @@ -1,7 +1,6 @@ /* See LICENSE file for copyright and license details. */ #include <sys/stat.h> #include <sys/types.h> -#include <sys/wait.h> #include <curses.h> #include <dirent.h> @@ -20,21 +19,12 @@ #include "util.h" -#define NR_ARGS 32 -#define LEN(x) (sizeof(x) / sizeof(*(x))) #undef MIN #define MIN(x, y) ((x) < (y) ? (x) : (y)) #define ISODD(x) ((x) & 1) #define CONTROL(c) ((c) ^ 0x40) #define META(c) ((c) ^ 0x80) -struct assoc { - char *regex; /* Regex to match on filename */ - char *file; - char *argv[NR_ARGS]; - regex_t regcomp; -}; - struct cpair { int fg; int bg; @@ -71,7 +61,7 @@ struct key { char *env; /* Environment variable to run */ }; -#include "config.h" +#include "noiceconf.h" struct entry { char name[PATH_MAX]; @@ -167,59 +157,6 @@ xdirname(const char *path) return out; } -void -spawnvp(char *dir, char *file, char *argv[]) -{ - pid_t pid; - int status; - - pid = fork(); - if (pid == 0) { - if (dir != NULL) - chdir(dir); - execvp(file, argv); - _exit(1); - } else { - /* Ignore interruptions */ - while (waitpid(pid, &status, 0) == -1) - DPRINTF_D(status); - DPRINTF_D(pid); - } -} - -void -spawnlp(char *dir, char *file, char *argv0, ...) -{ - char *argv[NR_ARGS]; - va_list ap; - int argc; - - va_start(ap, argv0); - argv[0] = argv0; - for (argc = 1; argv[argc] = va_arg(ap, char *); argc++) - ; - argv[argc] = NULL; - va_end(ap); - spawnvp(dir, file, argv); -} - -void -spawnassoc(struct assoc *assoc, char *arg) -{ - char *argv[NR_ARGS]; - int i; - - for (i = 0; assoc->argv[i]; i++) { - if (strcmp(assoc->argv[i], "{}") == 0) { - argv[i] = arg; - continue; - } - argv[i] = assoc->argv[i]; - } - argv[i] = NULL; - spawnvp(NULL, assoc->file, argv); -} - char * xgetenv(char *name, char *fallback) { @@ -231,21 +168,6 @@ xgetenv(char *name, char *fallback) return value && value[0] ? value : fallback; } -struct assoc * -openwith(char *file) -{ - int i; - - for (i = 0; i < LEN(assocs); i++) { - if (regexec(&assocs[i].regcomp, file, 0, NULL, 0) == 0) { - DPRINTF_S(assocs[i].argv[0]); - return &assocs[i]; - } - } - - return NULL; -} - int setfilter(regex_t *regex, char *filter) { @@ -671,7 +593,6 @@ browse(char *ipath, char *ifilter) char path[PATH_MAX], oldpath[PATH_MAX], newpath[PATH_MAX]; char fltr[LINE_MAX]; char *dir, *tmp, *run, *env; - struct assoc *assoc; struct stat sb; regex_t re; int r, fd; @@ -744,13 +665,8 @@ nochange: strlcpy(fltr, ifilter, sizeof(fltr)); goto begin; case S_IFREG: - assoc = openwith(newpath); - if (assoc == NULL) { - printmsg("No association"); - goto nochange; - } exitcurses(); - spawnassoc(assoc, newpath); + spawnlp(path, "nopen", "nopen", newpath, (void *)0); initcurses(); continue; default: @@ -869,7 +785,7 @@ nochange: mkpath(path, dents[cur].name, oldpath, sizeof(oldpath)); run = xgetenv(env, run); exitcurses(); - spawnlp(path, run, run, NULL); + spawnlp(path, run, run, (void *)0); initcurses(); goto begin; case SEL_RUNARG: @@ -878,7 +794,7 @@ nochange: mkpath(path, dents[cur].name, oldpath, sizeof(oldpath)); run = xgetenv(env, run); exitcurses(); - spawnlp(path, run, run, dents[cur].name, NULL); + spawnlp(path, run, run, dents[cur].name, (void *)0); initcurses(); goto begin; } @@ -886,31 +802,13 @@ nochange: if (idletimeout != 0 && idle == idletimeout) { idle = 0; exitcurses(); - spawnlp(NULL, idlecmd, idlecmd, NULL); + spawnlp(NULL, idlecmd, idlecmd, (void *)0); initcurses(); } } } void -initassocs(void) -{ - char errbuf[256]; - int i, r; - - for (i = 0; i < LEN(assocs); i++) { - r = regcomp(&assocs[i].regcomp, assocs[i].regex, - REG_NOSUB | REG_EXTENDED | REG_ICASE); - if (r != 0) { - regerror(r, &assocs[i].regcomp, errbuf, sizeof(errbuf)); - fprintf(stderr, "invalid regex assocs[%d]: %s: %s\n", - i, assocs[i].regex, errbuf); - exit(1); - } - } -} - -void usage(char *argv0) { fprintf(stderr, "usage: %s [dir]\n", argv0); @@ -954,7 +852,6 @@ main(int argc, char *argv[]) /* Set locale before curses setup */ setlocale(LC_ALL, ""); - initassocs(); initcurses(); browse(ipath, ifilter); exitcurses(); diff --git a/noiceconf.def.h b/noiceconf.def.h @@ -0,0 +1,93 @@ +/* See LICENSE file for copyright and license details. */ +#define CWD "cwd: " +#define CURSR " > " +#define EMPTY " " + +int dirorder = 0; /* Set to 1 to sort by directory first */ +int mtimeorder = 0; /* Set to 1 to sort by time modified */ +int icaseorder = 0; /* Set to 1 to sort by ignoring case */ +int versorder = 0; /* Set to 1 to sort by version number */ +int idletimeout = 0; /* Screensaver timeout in seconds, 0 to disable */ +int showhidden = 0; /* Set to 1 to show hidden files by default */ +int usecolor = 0; /* Set to 1 to enable color attributes */ +char *idlecmd = "rain"; /* The screensaver program */ + +/* See curs_attr(3) for valid video attributes */ +#define CURSR_ATTR A_NORMAL +#define DIR_ATTR A_NORMAL | COLOR_PAIR(4) +#define LINK_ATTR A_NORMAL | COLOR_PAIR(6) +#define SOCK_ATTR A_NORMAL | COLOR_PAIR(1) +#define FIFO_ATTR A_NORMAL | COLOR_PAIR(5) +#define EXEC_ATTR A_NORMAL | COLOR_PAIR(2) + +/* Colors to use with COLOR_PAIR(n) as attributes */ +struct cpair pairs[] = { + { .fg = 0, .bg = 0 }, + /* pairs start at 1 */ + { COLOR_RED, -1 }, + { COLOR_GREEN, -1 }, + { COLOR_YELLOW, -1 }, + { COLOR_BLUE, -1 }, + { COLOR_MAGENTA, -1 }, + { COLOR_CYAN, -1 }, +}; + +struct key bindings[] = { + /* Quit */ + { 'q', SEL_QUIT }, + /* Back */ + { KEY_BACKSPACE, SEL_BACK }, + { KEY_LEFT, SEL_BACK }, + { 'h', SEL_BACK }, + { CONTROL('H'), SEL_BACK }, + /* Inside */ + { KEY_ENTER, SEL_GOIN }, + { '\r', SEL_GOIN }, + { KEY_RIGHT, SEL_GOIN }, + { 'l', SEL_GOIN }, + /* Filter */ + { '/', SEL_FLTR }, + { '&', SEL_FLTR }, + /* Next */ + { 'j', SEL_NEXT }, + { KEY_DOWN, SEL_NEXT }, + { CONTROL('N'), SEL_NEXT }, + /* Previous */ + { 'k', SEL_PREV }, + { KEY_UP, SEL_PREV }, + { CONTROL('P'), SEL_PREV }, + /* Page down */ + { KEY_NPAGE, SEL_PGDN }, + { CONTROL('D'), SEL_PGDN }, + /* Page up */ + { KEY_PPAGE, SEL_PGUP }, + { CONTROL('U'), SEL_PGUP }, + /* Home */ + { KEY_HOME, SEL_HOME }, + { META('<'), SEL_HOME }, + { '^', SEL_HOME }, + /* End */ + { KEY_END, SEL_END }, + { META('>'), SEL_END }, + { '$', SEL_END }, + /* Change dir */ + { 'c', SEL_CD }, + { '~', SEL_CDHOME }, + /* Toggle hide .dot files */ + { '.', SEL_TOGGLEDOT }, + /* Toggle sort by directory first */ + { 'd', SEL_DSORT }, + /* Toggle sort by time */ + { 't', SEL_MTIME }, + /* Toggle case sensitivity */ + { 'i', SEL_ICASE }, + /* Toggle sort by version number */ + { 'v', SEL_VERS }, + { CONTROL('L'), SEL_REDRAW }, + /* Run command */ + { 'z', SEL_RUN, "top" }, + { '!', SEL_RUN, "sh", "SHELL" }, + /* Run command with argument */ + { 'e', SEL_RUNARG, "vi", "EDITOR" }, + { 'p', SEL_RUNARG, "less", "PAGER" }, +}; diff --git a/nopen.1 b/nopen.1 @@ -0,0 +1,31 @@ +.Dd August 2, 2019 +.Dt NOPEN 1 +.Os +.Sh NAME +.Nm nopen +.Nd opens a file in the user's preferred application +.Sh SYNOPSIS +.Nm +.Ar file... +.Sh DESCRIPTION +.Nm +opens the files provided as arguments with the user's proferred +application. +.Pp +The file associations are specified by regexes +matching on the currently selected filename. +If a match is found the associated program is executed +with the filename passed in as the argument. +If no match is found the program +.Xr less 1 +is invoked. +.Sh CONFIGURATION +.Nm +is configured by modifying +.Pa nopenconf.h +and recompiling the code. +.Sh SEE ALSO +.Xr noice 1 +.Sh AUTHORS +.An Lazaros Koromilas Aq Mt lostd@2f30.org , +.An Dimitris Papastamos Aq Mt sin@2f30.org . diff --git a/nopen.c b/nopen.c @@ -0,0 +1,95 @@ +/* See LICENSE file for copyright and license details. */ +#include <sys/types.h> +#include <sys/wait.h> + +#include <err.h> +#include <regex.h> +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <unistd.h> + +#include "util.h" + +struct assoc { + char *regex; /* Regex to match on filename */ + char *file; + char *argv[NR_ARGS]; + regex_t regcomp; +}; + +#include "nopenconf.h" + +void +spawnassoc(struct assoc *assoc, char *arg) +{ + char *argv[NR_ARGS]; + int i; + + for (i = 0; assoc->argv[i]; i++) { + if (strcmp(assoc->argv[i], "{}") == 0) { + argv[i] = arg; + continue; + } + argv[i] = assoc->argv[i]; + } + argv[i] = NULL; + spawnvp(NULL, assoc->file, argv); +} + +struct assoc * +openwith(char *file) +{ + int i; + + for (i = 0; i < LEN(assocs); i++) { + if (regexec(&assocs[i].regcomp, file, 0, NULL, 0) == 0) + return &assocs[i]; + } + + return NULL; +} + +void +initassocs(void) +{ + char errbuf[256]; + int i, r; + + for (i = 0; i < LEN(assocs); i++) { + r = regcomp(&assocs[i].regcomp, assocs[i].regex, + REG_NOSUB | REG_EXTENDED | REG_ICASE); + if (r != 0) { + regerror(r, &assocs[i].regcomp, errbuf, sizeof(errbuf)); + fprintf(stderr, "invalid regex assocs[%d]: %s: %s\n", + i, assocs[i].regex, errbuf); + exit(1); + } + } +} + +void +usage(char *argv0) +{ + fprintf(stderr, "usage: %s file...\n", argv0); + exit(1); +} + +int +main(int argc, char *argv[]) +{ + if (argc == 1) + usage(argv[0]); + argc--; + argv++; + initassocs(); + for (; *argv != NULL; argv++) { + struct assoc *assoc; + + assoc = openwith(argv[0]); + if (assoc == NULL) + continue; + spawnassoc(assoc, argv[0]); + } + return 0; +} diff --git a/nopenconf.def.h b/nopenconf.def.h @@ -0,0 +1,9 @@ +/* See LICENSE file for copyright and license details. */ +struct assoc assocs[] = { + { .regex = "\\.(avi|mp4|mkv|mp3|ogg|flac|mov)$", .file = "mpv", .argv = { "mpv", "{}", NULL } }, + { .regex = "\\.(png|jpg|gif)$", .file = "sxiv", .argv = { "sxiv", "{}", NULL} }, + { .regex = "\\.(html|svg)$", .file = "firefox", .argv = { "firefox", "{}", NULL } }, + { .regex = "\\.pdf$", .file = "mupdf", .argv = { "mupdf", "{}", NULL} }, + { .regex = "\\.sh$", .file = "sh", .argv = { "sh", "{}", NULL} }, + { .regex = ".", .file = "less", .argv = { "less", "{}", NULL } }, +}; diff --git a/spawn.c b/spawn.c @@ -0,0 +1,43 @@ +/* See LICENSE file for copyright and license details. */ +#include <sys/types.h> +#include <sys/wait.h> + +#include <stdarg.h> +#include <unistd.h> + +#include "util.h" + +void +spawnvp(char *dir, char *file, char *argv[]) +{ + pid_t pid; + int status; + + pid = fork(); + if (pid == 0) { + if (dir != NULL) + chdir(dir); + execvp(file, argv); + _exit(1); + } else { + /* Ignore interruptions */ + while (waitpid(pid, &status, 0) == -1) + ; + } +} + +void +spawnlp(char *dir, char *file, char *argv0, ...) +{ + char *argv[NR_ARGS]; + va_list ap; + int argc; + + va_start(ap, argv0); + argv[0] = argv0; + for (argc = 1; argv[argc] = va_arg(ap, char *); argc++) + ; + argv[argc] = NULL; + va_end(ap); + spawnvp(dir, file, argv); +} diff --git a/strverscmp.c b/strverscmp.c @@ -1,6 +1,8 @@ +/* See LICENSE file for copyright and license details. */ #include <ctype.h> #include <stdlib.h> #include <string.h> + #include "util.h" int diff --git a/util.h b/util.h @@ -1,12 +1,6 @@ /* See LICENSE file for copyright and license details. */ -#undef strlcat -size_t strlcat(char *, const char *, size_t); -#undef strlcpy -size_t strlcpy(char *, const char *, size_t); -#undef dprintf -int dprintf(int, const char *, ...); -#undef strverscmp -int strverscmp(const char *, const char *); +#define LEN(x) (sizeof(x) / sizeof(*(x))) +#define NR_ARGS 32 #ifdef DEBUG #define DEBUG_FD 8 @@ -22,3 +16,14 @@ int strverscmp(const char *, const char *); #define DPRINTF_P(x) #define DPRINTF_LLU(x) #endif /* DEBUG */ + +#undef strlcat +size_t strlcat(char *, const char *, size_t); +#undef strlcpy +size_t strlcpy(char *, const char *, size_t); +#undef dprintf +int dprintf(int, const char *, ...); + +int strverscmp(const char *, const char *); +void spawnvp(char *, char *, char *[]); +void spawnlp(char *, char *, char *, ...);