From e7f802ce61308cff6bec6c0a3e8bf183484c8a3b Mon Sep 17 00:00:00 2001 From: dteske Date: Tue, 25 Nov 2014 22:16:43 +0000 Subject: [PATCH] Revert revisions 275047, 275051, and 275056. Oops, dpv(1,3) requires dialog-1.2-20130923 or higher (which I introduced to HEAD via r255852 prior to the creation of the stable/10 branch; however it never got merged to stable/9 so we can't have dpv in stable/9). Brief summary of reverted revisions: r275047: Add dpv(1,3)/figpar(3) r275051: Fixes r275056: Enable compilation of dpv(1,3) Pointy-hat: me git-svn-id: svn://svn.freebsd.org/base/stable/9@275081 ccf9f872-aa2e-dd11-9fc8-001c23d0bc1f --- Makefile.inc1 | 6 +- gnu/lib/libdialog/Makefile | 3 - lib/Makefile | 3 - lib/libdpv/Makefile | 18 - lib/libdpv/dialog_util.c | 633 ------------------------------ lib/libdpv/dialog_util.h | 73 ---- lib/libdpv/dialogrc.c | 359 ----------------- lib/libdpv/dialogrc.h | 56 --- lib/libdpv/dprompt.c | 770 ------------------------------------- lib/libdpv/dprompt.h | 59 --- lib/libdpv/dpv.3 | 510 ------------------------ lib/libdpv/dpv.c | 721 ---------------------------------- lib/libdpv/dpv.h | 161 -------- lib/libdpv/dpv_private.h | 66 ---- lib/libdpv/status.c | 111 ------ lib/libdpv/status.h | 43 --- lib/libdpv/util.c | 107 ------ lib/libdpv/util.h | 50 --- lib/libfigpar/Makefile | 21 - lib/libfigpar/figpar.3 | 251 ------------ lib/libfigpar/figpar.c | 469 ---------------------- lib/libfigpar/figpar.h | 99 ----- lib/libfigpar/string_m.c | 309 --------------- lib/libfigpar/string_m.h | 43 --- share/mk/bsd.libnames.mk | 2 - sys/sys/param.h | 2 +- usr.bin/Makefile | 1 - usr.bin/dpv/Makefile | 12 - usr.bin/dpv/dpv.1 | 430 --------------------- usr.bin/dpv/dpv.c | 541 -------------------------- usr.bin/dpv/dpv_util.h | 68 ---- 31 files changed, 2 insertions(+), 5995 deletions(-) delete mode 100644 lib/libdpv/Makefile delete mode 100644 lib/libdpv/dialog_util.c delete mode 100644 lib/libdpv/dialog_util.h delete mode 100644 lib/libdpv/dialogrc.c delete mode 100644 lib/libdpv/dialogrc.h delete mode 100644 lib/libdpv/dprompt.c delete mode 100644 lib/libdpv/dprompt.h delete mode 100644 lib/libdpv/dpv.3 delete mode 100644 lib/libdpv/dpv.c delete mode 100644 lib/libdpv/dpv.h delete mode 100644 lib/libdpv/dpv_private.h delete mode 100644 lib/libdpv/status.c delete mode 100644 lib/libdpv/status.h delete mode 100644 lib/libdpv/util.c delete mode 100644 lib/libdpv/util.h delete mode 100644 lib/libfigpar/Makefile delete mode 100644 lib/libfigpar/figpar.3 delete mode 100644 lib/libfigpar/figpar.c delete mode 100644 lib/libfigpar/figpar.h delete mode 100644 lib/libfigpar/string_m.c delete mode 100644 lib/libfigpar/string_m.h delete mode 100644 usr.bin/dpv/Makefile delete mode 100644 usr.bin/dpv/dpv.1 delete mode 100644 usr.bin/dpv/dpv.c delete mode 100644 usr.bin/dpv/dpv_util.h diff --git a/Makefile.inc1 b/Makefile.inc1 index 61844e04f..184647b48 100644 --- a/Makefile.inc1 +++ b/Makefile.inc1 @@ -1353,7 +1353,6 @@ _prebuild_libs= ${_kerberos5_lib_libasn1} ${_kerberos5_lib_libhdb} \ ${_kerberos5_lib_libroken} \ lib/libbz2 lib/libcom_err lib/libcrypt \ lib/libelf lib/libexpat \ - lib/libfigpar \ ${_lib_libgssapi} ${_lib_libipx} \ lib/libkiconv lib/libkvm lib/liblzma lib/libmd \ lib/ncurses/ncurses lib/ncurses/ncursesw \ @@ -1364,8 +1363,7 @@ _prebuild_libs= ${_kerberos5_lib_libasn1} ${_kerberos5_lib_libhdb} \ ${_cddl_lib_libzfs_core} \ lib/libutil ${_lib_libypclnt} lib/libz lib/msun \ ${_secure_lib_libcrypto} ${_lib_libldns} \ - ${_secure_lib_libssh} ${_secure_lib_libssl} \ - gnu/lib/libdialog + ${_secure_lib_libssh} ${_secure_lib_libssl} .if ${MK_LIBTHR} != "no" _lib_libthr= lib/libthr @@ -1445,8 +1443,6 @@ _lib_libypclnt= lib/libypclnt lib/libradius__L: lib/libmd__L .endif -gnu/lib/libdialog__L: lib/msun__L lib/ncurses/ncursesw__L - .for _lib in ${_prereq_libs} ${_lib}__PL: .PHONY .if exists(${.CURDIR}/${_lib}) diff --git a/gnu/lib/libdialog/Makefile b/gnu/lib/libdialog/Makefile index c5b883055..f0979ac92 100644 --- a/gnu/lib/libdialog/Makefile +++ b/gnu/lib/libdialog/Makefile @@ -13,9 +13,6 @@ SRCS= argv.c arrows.c buttons.c calendar.c checklist.c columns.c \ INCS= dialog.h dlg_colors.h dlg_config.h dlg_keys.h MAN= dialog.3 -DPADD= ${LIBNCURSESW} ${LIBM} -LDADD= -lncursesw -lm - CFLAGS+= -I${.CURDIR} -I${DIALOG} -D_XOPEN_SOURCE_EXTENDED .PATH: ${DIALOG} WARNS?= 1 diff --git a/lib/Makefile b/lib/Makefile index 6168889e2..734bc0dc7 100644 --- a/lib/Makefile +++ b/lib/Makefile @@ -22,7 +22,6 @@ # libsbuf must be built before libcam. # libtacplus must be built before libpam. # libutil must be built before libpam. -# libfigpar must be built before libdpv (but after ncurses and libutil). # libypclnt must be built before libpam. # libgssapi must be built before librpcsec_gss # @@ -49,7 +48,6 @@ SUBDIR_ORDERED= ${_csu} \ libsbuf \ libtacplus \ libutil \ - libfigpar \ ${_libypclnt} \ ${_libcxxrt} \ ${_libcplusplus} @@ -69,7 +67,6 @@ SUBDIR= ${SUBDIR_ORDERED} \ libdevinfo \ libdevstat \ libdisk \ - libdpv \ libdwarf \ libedit \ ${_libefi} \ diff --git a/lib/libdpv/Makefile b/lib/libdpv/Makefile deleted file mode 100644 index 8096cc92c..000000000 --- a/lib/libdpv/Makefile +++ /dev/null @@ -1,18 +0,0 @@ -# $FreeBSD$ - -LIB= dpv -SHLIB_MAJOR= 1 -INCS= dpv.h -MAN= dpv.3 -MLINKS= dpv.3 dpv_free.3 - -DPADD= ${LIBDIALOG} ${LIBFIGPAR} ${LIBNCURSESW} ${LIBUTIL} -LDADD= -ldialog -lfigpar -lncursesw -lutil - -SRCS= dialog_util.c dialogrc.c dprompt.c dpv.c status.c util.c - -CFLAGS+= -I${.CURDIR} - -WARNS?= 6 - -.include diff --git a/lib/libdpv/dialog_util.c b/lib/libdpv/dialog_util.c deleted file mode 100644 index d047a25e5..000000000 --- a/lib/libdpv/dialog_util.c +++ /dev/null @@ -1,633 +0,0 @@ -/*- - * Copyright (c) 2013-2014 Devin Teske - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - */ - -#include -__FBSDID("$FreeBSD$"); - -#include - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include "dialog_util.h" -#include "dpv.h" -#include "dpv_private.h" - -extern char **environ; - -#define TTY_DEFAULT_ROWS 24 -#define TTY_DEFAULT_COLS 80 - -/* [X]dialog(1) characteristics */ -uint8_t dialog_test = 0; -uint8_t use_dialog = 0; -uint8_t use_libdialog = 1; -uint8_t use_xdialog = 0; -uint8_t use_color = 1; -char dialog[PATH_MAX] = DIALOG; - -/* [X]dialog(1) functionality */ -char *title = NULL; -char *backtitle = NULL; -int dheight = 0; -int dwidth = 0; -static char *dargv[64] = { NULL }; - -/* TTY/Screen characteristics */ -static struct winsize *maxsize = NULL; - -/* Function prototypes */ -static void tty_maxsize_update(void); -static void x11_maxsize_update(void); - -/* - * Update row/column fields of `maxsize' global (used by dialog_maxrows() and - * dialog_maxcols()). If the `maxsize' pointer is NULL, it will be initialized. - * The `ws_row' and `ws_col' fields of `maxsize' are updated to hold current - * maximum height and width (respectively) for a dialog(1) widget based on the - * active TTY size. - * - * This function is called automatically by dialog_maxrows/cols() to reflect - * changes in terminal size in-between calls. - */ -static void -tty_maxsize_update(void) -{ - int fd = STDIN_FILENO; - struct termios t; - - if (maxsize == NULL) { - if ((maxsize = malloc(sizeof(struct winsize))) == NULL) - errx(EXIT_FAILURE, "Out of memory?!"); - memset((void *)maxsize, '\0', sizeof(struct winsize)); - } - - if (!isatty(fd)) - fd = open("/dev/tty", O_RDONLY); - if ((tcgetattr(fd, &t) < 0) || (ioctl(fd, TIOCGWINSZ, maxsize) < 0)) { - maxsize->ws_row = TTY_DEFAULT_ROWS; - maxsize->ws_col = TTY_DEFAULT_COLS; - } -} - -/* - * Update row/column fields of `maxsize' global (used by dialog_maxrows() and - * dialog_maxcols()). If the `maxsize' pointer is NULL, it will be initialized. - * The `ws_row' and `ws_col' fields of `maxsize' are updated to hold current - * maximum height and width (respectively) for an Xdialog(1) widget based on - * the active video resolution of the X11 environment. - * - * This function is called automatically by dialog_maxrows/cols() to initialize - * `maxsize'. Since video resolution changes are less common and more obtrusive - * than changes to terminal size, the dialog_maxrows/cols() functions only call - * this function when `maxsize' is set to NULL. - */ -static void -x11_maxsize_update(void) -{ - FILE *f = NULL; - char *cols; - char *cp; - char *rows; - char cmdbuf[LINE_MAX]; - char rbuf[LINE_MAX]; - - if (maxsize == NULL) { - if ((maxsize = malloc(sizeof(struct winsize))) == NULL) - errx(EXIT_FAILURE, "Out of memory?!"); - memset((void *)maxsize, '\0', sizeof(struct winsize)); - } - - /* Assemble the command necessary to get X11 sizes */ - snprintf(cmdbuf, LINE_MAX, "%s --print-maxsize 2>&1", dialog); - - fflush(STDIN_FILENO); /* prevent popen(3) from seeking on stdin */ - - if ((f = popen(cmdbuf, "r")) == NULL) { - if (debug) - warnx("WARNING! Command `%s' failed", cmdbuf); - return; - } - - /* Read in the line returned from Xdialog(1) */ - if ((fgets(rbuf, LINE_MAX, f) == NULL) || (pclose(f) < 0)) - return; - - /* Check for X11-related errors */ - if (strncmp(rbuf, "Xdialog: Error", 14) == 0) - return; - - /* Parse expected output: MaxSize: YY, XXX */ - if ((rows = strchr(rbuf, ' ')) == NULL) - return; - if ((cols = strchr(rows, ',')) != NULL) { - /* strtonum(3) doesn't like trailing junk */ - *(cols++) = '\0'; - if ((cp = strchr(cols, '\n')) != NULL) - *cp = '\0'; - } - - /* Convert to unsigned short */ - maxsize->ws_row = (unsigned short)strtonum( - rows, 0, USHRT_MAX, (const char **)NULL); - maxsize->ws_col = (unsigned short)strtonum( - cols, 0, USHRT_MAX, (const char **)NULL); -} - -/* - * Return the current maximum height (rows) for an [X]dialog(1) widget. - */ -int -dialog_maxrows(void) -{ - - if (use_xdialog && maxsize == NULL) - x11_maxsize_update(); /* initialize maxsize for GUI */ - else if (!use_xdialog) - tty_maxsize_update(); /* update maxsize for TTY */ - return (maxsize->ws_row); -} - -/* - * Return the current maximum width (cols) for an [X]dialog(1) widget. - */ -int -dialog_maxcols(void) -{ - - if (use_xdialog && maxsize == NULL) - x11_maxsize_update(); /* initialize maxsize for GUI */ - else if (!use_xdialog) - tty_maxsize_update(); /* update maxsize for TTY */ - - if (use_dialog || use_libdialog) { - if (use_shadow) - return (maxsize->ws_col - 2); - else - return (maxsize->ws_col); - } else - return (maxsize->ws_col); -} - -/* - * Return the current maximum width (cols) for the terminal. - */ -int -tty_maxcols(void) -{ - - if (use_xdialog && maxsize == NULL) - x11_maxsize_update(); /* initialize maxsize for GUI */ - else if (!use_xdialog) - tty_maxsize_update(); /* update maxsize for TTY */ - - return (maxsize->ws_col); -} - -/* - * Spawn an [X]dialog(1) `--gauge' box with a `--prompt' value of init_prompt. - * Writes the resulting process ID to the pid_t pointed at by `pid'. Returns a - * file descriptor (int) suitable for writing data to the [X]dialog(1) instance - * (data written to the file descriptor is seen as standard-in by the spawned - * [X]dialog(1) process). - */ -int -dialog_spawn_gauge(char *init_prompt, pid_t *pid) -{ - char dummy_init[2] = ""; - char *cp; - int height; - int width; - int error; - posix_spawn_file_actions_t action; -#if DIALOG_SPAWN_DEBUG - unsigned int i; -#endif - unsigned int n = 0; - int stdin_pipe[2] = { -1, -1 }; - - /* Override `dialog' with a path from ENV_DIALOG if provided */ - if ((cp = getenv(ENV_DIALOG)) != NULL) - snprintf(dialog, PATH_MAX, "%s", cp); - - /* For Xdialog(1), set ENV_XDIALOG_HIGH_DIALOG_COMPAT */ - setenv(ENV_XDIALOG_HIGH_DIALOG_COMPAT, "1", 1); - - /* Constrain the height/width */ - height = dialog_maxrows(); - if (backtitle != NULL) - height -= use_shadow ? 5 : 4; - if (dheight < height) - height = dheight; - width = dialog_maxcols(); - if (dwidth < width) - width = dwidth; - - /* Populate argument array */ - dargv[n++] = dialog; - if (title != NULL) { - if ((dargv[n] = malloc(8)) == NULL) - errx(EXIT_FAILURE, "Out of memory?!"); - sprintf(dargv[n++], "--title"); - dargv[n++] = title; - } - if (backtitle != NULL) { - if ((dargv[n] = malloc(12)) == NULL) - errx(EXIT_FAILURE, "Out of memory?!"); - sprintf(dargv[n++], "--backtitle"); - dargv[n++] = backtitle; - } - if (use_color) { - if ((dargv[n] = malloc(11)) == NULL) - errx(EXIT_FAILURE, "Out of memory?!"); - sprintf(dargv[n++], "--colors"); - } - if (use_xdialog) { - if ((dargv[n] = malloc(7)) == NULL) - errx(EXIT_FAILURE, "Out of memory?!"); - sprintf(dargv[n++], "--left"); - - /* - * NOTE: Xdialog(1)'s `--wrap' appears to be broken for the - * `--gauge' widget prompt-updates. Add it anyway (in-case it - * gets fixed in some later release). - */ - if ((dargv[n] = malloc(7)) == NULL) - errx(EXIT_FAILURE, "Out of memory?!"); - sprintf(dargv[n++], "--wrap"); - } - if ((dargv[n] = malloc(8)) == NULL) - errx(EXIT_FAILURE, "Out of memory?!"); - sprintf(dargv[n++], "--gauge"); - dargv[n++] = use_xdialog ? dummy_init : init_prompt; - if ((dargv[n] = malloc(40)) == NULL) - errx(EXIT_FAILURE, "Out of memory?!"); - snprintf(dargv[n++], 40, "%u", height); - if ((dargv[n] = malloc(40)) == NULL) - errx(EXIT_FAILURE, "Out of memory?!"); - snprintf(dargv[n++], 40, "%u", width); - dargv[n] = NULL; - - /* Open a pipe(2) to communicate with [X]dialog(1) */ - if (pipe(stdin_pipe) < 0) - err(EXIT_FAILURE, "%s: pipe(2)", __func__); - - /* Fork [X]dialog(1) process */ -#if DIALOG_SPAWN_DEBUG - fprintf(stderr, "%s: spawning `", __func__); - for (i = 0; i < n; i++) { - if (i == 0) - fprintf(stderr, "%s", dargv[i]); - else if (*dargv[i] == '-' && *(dargv[i] + 1) == '-') - fprintf(stderr, " %s", dargv[i]); - else - fprintf(stderr, " \"%s\"", dargv[i]); - } - fprintf(stderr, "'\n"); -#endif - posix_spawn_file_actions_init(&action); - posix_spawn_file_actions_adddup2(&action, stdin_pipe[0], STDIN_FILENO); - posix_spawn_file_actions_addclose(&action, stdin_pipe[1]); - error = posix_spawnp(pid, dialog, &action, - (const posix_spawnattr_t *)NULL, dargv, environ); - if (error != 0) - err(EXIT_FAILURE, "%s: posix_spawnp(3)", __func__); - - /* NB: Do not free(3) *dargv[], else SIGSEGV */ - - return (stdin_pipe[1]); -} - -/* - * Returns the number of lines in buffer pointed to by `prompt'. Takes both - * newlines and escaped-newlines into account. - */ -unsigned int -dialog_prompt_numlines(const char *prompt, uint8_t nlstate) -{ - uint8_t nls = nlstate; /* See dialog_prompt_nlstate() */ - const char *cp = prompt; - unsigned int nlines = 1; - - if (prompt == NULL || *prompt == '\0') - return (0); - - while (*cp != '\0') { - if (use_dialog) { - if (strncmp(cp, "\\n", 2) == 0) { - cp++; - nlines++; - nls = TRUE; /* See declaration comment */ - } else if (*cp == '\n') { - if (!nls) - nlines++; - nls = FALSE; /* See declaration comment */ - } - } else if (use_libdialog) { - if (*cp == '\n') - nlines++; - } else if (strncmp(cp, "\\n", 2) == 0) { - cp++; - nlines++; - } - cp++; - } - - return (nlines); -} - -/* - * Returns the length in bytes of the longest line in buffer pointed to by - * `prompt'. Takes newlines and escaped newlines into account. Also discounts - * dialog(1) color escape codes if enabled (via `use_color' global). - */ -unsigned int -dialog_prompt_longestline(const char *prompt, uint8_t nlstate) -{ - uint8_t backslash = 0; - uint8_t nls = nlstate; /* See dialog_prompt_nlstate() */ - const char *p = prompt; - int longest = 0; - int n = 0; - - /* `prompt' parameter is required */ - if (prompt == NULL) - return (0); - if (*prompt == '\0') - return (0); /* shortcut */ - - /* Loop until the end of the string */ - while (*p != '\0') { - /* dialog(1) and dialog(3) will render literal newlines */ - if (use_dialog || use_libdialog) { - if (*p == '\n') { - if (!use_libdialog && nls) - n++; - else { - if (n > longest) - longest = n; - n = 0; - } - nls = FALSE; /* See declaration comment */ - p++; - continue; - } - } - - /* Check for backslash character */ - if (*p == '\\') { - /* If second backslash, count as a single-char */ - if ((backslash ^= 1) == 0) - n++; - } else if (backslash) { - if (*p == 'n' && !use_libdialog) { /* new line */ - /* NB: dialog(3) ignores escaped newlines */ - nls = TRUE; /* See declaration comment */ - if (n > longest) - longest = n; - n = 0; - } else if (use_color && *p == 'Z') { - if (*++p != '\0') - p++; - backslash = 0; - continue; - } else /* [X]dialog(1)/dialog(3) only expand those */ - n += 2; - - backslash = 0; - } else - n++; - p++; - } - if (n > longest) - longest = n; - - return (longest); -} - -/* - * Returns a pointer to the last line in buffer pointed to by `prompt'. Takes - * both newlines (if using dialog(1) versus Xdialog(1)) and escaped newlines - * into account. If no newlines (escaped or otherwise) appear in the buffer, - * `prompt' is returned. If passed a NULL pointer, returns NULL. - */ -char * -dialog_prompt_lastline(char *prompt, uint8_t nlstate) -{ - uint8_t nls = nlstate; /* See dialog_prompt_nlstate() */ - char *lastline; - char *p; - - if (prompt == NULL) - return (NULL); - if (*prompt == '\0') - return (prompt); /* shortcut */ - - lastline = p = prompt; - while (*p != '\0') { - /* dialog(1) and dialog(3) will render literal newlines */ - if (use_dialog || use_libdialog) { - if (*p == '\n') { - if (use_libdialog || !nls) - lastline = p + 1; - nls = FALSE; /* See declaration comment */ - } - } - /* dialog(3) does not expand escaped newlines */ - if (use_libdialog) { - p++; - continue; - } - if (*p == '\\' && *(p + 1) != '\0' && *(++p) == 'n') { - nls = TRUE; /* See declaration comment */ - lastline = p + 1; - } - p++; - } - - return (lastline); -} - -/* - * Returns the number of extra lines generated by wrapping the text in buffer - * pointed to by `prompt' within `ncols' columns (for prompts, this should be - * dwidth - 4). Also discounts dialog(1) color escape codes if enabled (via - * `use_color' global). - */ -int -dialog_prompt_wrappedlines(char *prompt, int ncols, uint8_t nlstate) -{ - uint8_t backslash = 0; - uint8_t nls = nlstate; /* See dialog_prompt_nlstate() */ - char *cp; - char *p = prompt; - int n = 0; - int wlines = 0; - - /* `prompt' parameter is required */ - if (p == NULL) - return (0); - if (*p == '\0') - return (0); /* shortcut */ - - /* Loop until the end of the string */ - while (*p != '\0') { - /* dialog(1) and dialog(3) will render literal newlines */ - if (use_dialog || use_libdialog) { - if (*p == '\n') { - if (use_dialog || !nls) - n = 0; - nls = FALSE; /* See declaration comment */ - } - } - - /* Check for backslash character */ - if (*p == '\\') { - /* If second backslash, count as a single-char */ - if ((backslash ^= 1) == 0) - n++; - } else if (backslash) { - if (*p == 'n' && !use_libdialog) { /* new line */ - /* NB: dialog(3) ignores escaped newlines */ - nls = TRUE; /* See declaration comment */ - n = 0; - } else if (use_color && *p == 'Z') { - if (*++p != '\0') - p++; - backslash = 0; - continue; - } else /* [X]dialog(1)/dialog(3) only expand those */ - n += 2; - - backslash = 0; - } else - n++; - - /* Did we pass the width barrier? */ - if (n > ncols) { - /* - * Work backward to find the first whitespace on-which - * dialog(1) will wrap the line (but don't go before - * the start of this line). - */ - cp = p; - while (n > 1 && !isspace(*cp)) { - cp--; - n--; - } - if (n > 0 && isspace(*cp)) - p = cp; - wlines++; - n = 1; - } - - p++; - } - - return (wlines); -} - -/* - * Returns zero if the buffer pointed to by `prompt' contains an escaped - * newline but only if appearing after any/all literal newlines. This is - * specific to dialog(1) and does not apply to Xdialog(1). - * - * As an attempt to make shell scripts easier to read, dialog(1) will "eat" - * the first literal newline after an escaped newline. This however has a bug - * in its implementation in that rather than allowing `\\n\n' to be treated - * similar to `\\n' or `\n', dialog(1) expands the `\\n' and then translates - * the following literal newline (with or without characters between [!]) into - * a single space. - * - * If you want to be compatible with Xdialog(1), it is suggested that you not - * use literal newlines (they aren't supported); but if you have to use them, - * go right ahead. But be forewarned... if you set $DIALOG in your environment - * to something other than `cdialog' (our current dialog(1)), then it should - * do the same thing w/respect to how to handle a literal newline after an - * escaped newline (you could do no wrong by translating every literal newline - * into a space but only when you've previously encountered an escaped one; - * this is what dialog(1) is doing). - * - * The ``newline state'' (or nlstate for short; as I'm calling it) is helpful - * if you plan to combine multiple strings into a single prompt text. In lead- - * up to this procedure, a common task is to calculate and utilize the widths - * and heights of each piece of prompt text to later be combined. However, if - * (for example) the first string ends in a positive newline state (has an - * escaped newline without trailing literal), the first literal newline in the - * second string will be mangled. - * - * The return value of this function should be used as the `nlstate' argument - * to dialog_*() functions that require it to allow accurate calculations in - * the event such information is needed. - */ -uint8_t -dialog_prompt_nlstate(const char *prompt) -{ - const char *cp; - - if (prompt == NULL) - return 0; - - /* - * Work our way backward from the end of the string for efficiency. - */ - cp = prompt + strlen(prompt); - while (--cp >= prompt) { - /* - * If we get to a literal newline first, this prompt ends in a - * clean state for rendering with dialog(1). Otherwise, if we - * get to an escaped newline first, this prompt ends in an un- - * clean state (following literal will be mangled; see above). - */ - if (*cp == '\n') - return (0); - else if (*cp == 'n' && --cp > prompt && *cp == '\\') - return (1); - } - - return (0); /* no newlines (escaped or otherwise) */ -} - -/* - * Free allocated items initialized by tty_maxsize_update() and - * x11_maxsize_update() - */ -void -dialog_maxsize_free(void) -{ - if (maxsize != NULL) { - free(maxsize); - maxsize = NULL; - } -} diff --git a/lib/libdpv/dialog_util.h b/lib/libdpv/dialog_util.h deleted file mode 100644 index e279c3f06..000000000 --- a/lib/libdpv/dialog_util.h +++ /dev/null @@ -1,73 +0,0 @@ -/*- - * Copyright (c) 2013-2014 Devin Teske - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * $FreeBSD$ - */ - -#ifndef _DIALOG_UTIL_H_ -#define _DIALOG_UTIL_H_ - -#include - -#include "dialogrc.h" - -#define DIALOG_SPAWN_DEBUG 0 /* Debug spawning of [X]dialog(1) */ - -/* dialog(3) and [X]dialog(1) characteristics */ -#define DIALOG "dialog" -#define XDIALOG "Xdialog" -#define PROMPT_MAX 16384 -#define ENV_DIALOG "DIALOG" -#define ENV_USE_COLOR "USE_COLOR" -#define ENV_XDIALOG_HIGH_DIALOG_COMPAT "XDIALOG_HIGH_DIALOG_COMPAT" -extern uint8_t dialog_test; -extern uint8_t use_libdialog; -extern uint8_t use_dialog; -extern uint8_t use_xdialog; -extern uint8_t use_color; -extern char dialog[]; - -/* dialog(3) and [X]dialog(1) functionality */ -extern char *title, *backtitle; -extern int dheight, dwidth; - -__BEGIN_DECLS -uint8_t dialog_prompt_nlstate(const char *_prompt); -void dialog_gauge_free(void); -void dialog_maxsize_free(void); -char *dialog_prompt_lastline(char *_prompt, uint8_t _nlstate); -int dialog_maxcols(void); -int dialog_maxrows(void); -int dialog_prompt_wrappedlines(char *_prompt, int _ncols, - uint8_t _nlstate); -int dialog_spawn_gauge(char *_init_prompt, pid_t *_pid); -int tty_maxcols(void); -#define tty_maxrows() dialog_maxrows() -unsigned int dialog_prompt_longestline(const char *_prompt, - uint8_t _nlstate); -unsigned int dialog_prompt_numlines(const char *_prompt, uint8_t _nlstate); -__END_DECLS - -#endif /* !_DIALOG_UTIL_H_ */ diff --git a/lib/libdpv/dialogrc.c b/lib/libdpv/dialogrc.c deleted file mode 100644 index eb4a53621..000000000 --- a/lib/libdpv/dialogrc.c +++ /dev/null @@ -1,359 +0,0 @@ -/*- - * Copyright (c) 2013-2014 Devin Teske - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - */ - -#include -__FBSDID("$FreeBSD$"); - -#include - -#include -#include -#include -#include -#include -#include -#include -#include - -#include "dialogrc.h" - -#define STR_BUFSIZE 255 - -/* dialog(1) `.dialogrc' characteristics */ -uint8_t use_colors = 1; -uint8_t use_shadow = 1; -char gauge_color[STR_BUFSIZE] = "47b"; /* (BLUE,WHITE,ON) */ -char separator[STR_BUFSIZE] = ""; - -/* Function prototypes */ -static int setattr(struct fp_config *, uint32_t, char *, char *); -static int setbool(struct fp_config *, uint32_t, char *, char *); -static int setnum(struct fp_config *, uint32_t, char *, char *); -static int setstr(struct fp_config *, uint32_t, char *, char *); - -/* - * Anatomy of DIALOGRC (~/.dialogrc by default) - * NOTE: Must appear after private function prototypes (above) - * NB: Brace-initialization of union requires cast to *first* member of union - */ -static struct fp_config dialogrc_config[] = { - /* TYPE Directive DEFAULT HANDLER */ - {FP_TYPE_INT, "aspect", {(void *)0}, &setnum}, - {FP_TYPE_STR, "separate_widget", {separator}, &setstr}, - {FP_TYPE_INT, "tab_len", {(void *)0}, &setnum}, - {FP_TYPE_BOOL, "visit_items", {(void *)0}, &setbool}, - {FP_TYPE_BOOL, "use_shadow", {(void *)1}, &setbool}, - {FP_TYPE_BOOL, "use_colors", {(void *)1}, &setbool}, - {FP_TYPE_STR, "screen_color", {NULL}, &setattr}, - {FP_TYPE_STR, "shadow_color", {NULL}, &setattr}, - {FP_TYPE_STR, "dialog_color", {NULL}, &setattr}, - {FP_TYPE_STR, "title_color", {NULL}, &setattr}, - {FP_TYPE_STR, "border_color", {NULL}, &setattr}, - {FP_TYPE_STR, "button_active_color", {NULL}, &setattr}, - {FP_TYPE_STR, "button_inactive_color", {NULL}, &setattr}, - {FP_TYPE_STR, "button_key_active_color", {NULL}, &setattr}, - {FP_TYPE_STR, "button_key_inactive_color", {NULL}, &setattr}, - {FP_TYPE_STR, "button_label_active_color", {NULL}, &setattr}, - {FP_TYPE_STR, "button_label_inactive_color",{NULL}, &setattr}, - {FP_TYPE_STR, "inputbox_color", {NULL}, &setattr}, - {FP_TYPE_STR, "inputbox_border_color", {NULL}, &setattr}, - {FP_TYPE_STR, "searchbox_color", {NULL}, &setattr}, - {FP_TYPE_STR, "searchbox_title_color", {NULL}, &setattr}, - {FP_TYPE_STR, "searchbox_border_color", {NULL}, &setattr}, - {FP_TYPE_STR, "position_indicator_color", {NULL}, &setattr}, - {FP_TYPE_STR, "menubox_color", {NULL}, &setattr}, - {FP_TYPE_STR, "menubox_border_color", {NULL}, &setattr}, - {FP_TYPE_STR, "item_color", {NULL}, &setattr}, - {FP_TYPE_STR, "item_selected_color", {NULL}, &setattr}, - {FP_TYPE_STR, "tag_color", {NULL}, &setattr}, - {FP_TYPE_STR, "tag_selected_color", {NULL}, &setattr}, - {FP_TYPE_STR, "tag_key_color", {NULL}, &setattr}, - {FP_TYPE_STR, "tag_key_selected_color", {NULL}, &setattr}, - {FP_TYPE_STR, "check_color", {NULL}, &setattr}, - {FP_TYPE_STR, "check_selected_color", {NULL}, &setattr}, - {FP_TYPE_STR, "uarrow_color", {NULL}, &setattr}, - {FP_TYPE_STR, "darrow_color", {NULL}, &setattr}, - {FP_TYPE_STR, "itemhelp_color", {NULL}, &setattr}, - {FP_TYPE_STR, "form_active_text_color", {NULL}, &setattr}, - {FP_TYPE_STR, "form_text_color", {NULL}, &setattr}, - {FP_TYPE_STR, "form_item_readonly_color", {NULL}, &setattr}, - {FP_TYPE_STR, "gauge_color", {gauge_color}, &setattr}, - {0, NULL, {0}, NULL} -}; - -/* - * figpar call-back for interpreting value as .dialogrc `Attribute' - */ -static int -setattr(struct fp_config *option, uint32_t line __unused, - char *directive __unused, char *value) -{ - char *cp = value; - char *val; - size_t len; - char attrbuf[4]; - - if (option == NULL) { - warnx("%s:%d:%s: Missing callback parameter", __FILE__, - __LINE__, __func__); - return (-1); /* Abort processing */ - } - - /* Allocate memory for the data if not already done */ - if (option->value.str == NULL) { - if ((option->value.str = malloc(STR_BUFSIZE)) == NULL) - return (-1); - } - - /* - * If the first character is left-parenthesis, the format is - * `(background,foreground,highlight)' otherwise, we should take it - * as a reference to another color. - */ - if (*cp != '(') { - /* Copy the [current] value from the referenced color */ - val = dialogrc_config_option(cp)->value.str; - if (val != NULL) - snprintf(option->value.str, STR_BUFSIZE, "%s", val); - - return (0); - } else - cp++; - - strtolower(cp); - - /* Initialize the attrbuf (fg,bg,hi,NUL) */ - attrbuf[0] = '0'; - attrbuf[1] = '0'; - attrbuf[2] = 'B'; /* \ZB = disable; \Zb = enable (see dialog(1)) */ - attrbuf[3] = '\0'; - - /* Interpret the foreground color */ - if (strncmp(cp, "red,", 4) == 0) attrbuf[0] = '1'; - else if (strncmp(cp, "green,", 6) == 0) attrbuf[0] = '2'; - else if (strncmp(cp, "yellow,", 7) == 0) attrbuf[0] = '3'; - else if (strncmp(cp, "blue,", 5) == 0) attrbuf[0] = '4'; - else if (strncmp(cp, "magenta,", 8) == 0) attrbuf[0] = '5'; - else if (strncmp(cp, "cyan,", 5) == 0) attrbuf[0] = '6'; - else if (strncmp(cp, "white,", 6) == 0) attrbuf[0] = '7'; - else if (strncmp(cp, "black,", 6) == 0) attrbuf[0] = '8'; - - /* Advance to the background color */ - cp = strchr(cp, ','); - if (cp == NULL) - goto write_attrbuf; - else - cp++; - - /* Interpret the background color */ - if (strncmp(cp, "red,", 4) == 0) attrbuf[1] = '1'; - else if (strncmp(cp, "green,", 6) == 0) attrbuf[1] = '2'; - else if (strncmp(cp, "yellow,", 7) == 0) attrbuf[1] = '3'; - else if (strncmp(cp, "blue,", 5) == 0) attrbuf[1] = '4'; - else if (strncmp(cp, "magenta,", 8) == 0) attrbuf[1] = '5'; - else if (strncmp(cp, "cyan,", 5) == 0) attrbuf[1] = '6'; - else if (strncmp(cp, "white,", 6) == 0) attrbuf[1] = '7'; - else if (strncmp(cp, "black,", 6) == 0) attrbuf[1] = '8'; - - /* Advance to the highlight */ - cp = strchr(cp, ','); - if (cp == NULL) - goto write_attrbuf; - else - cp++; - - /* Trim trailing parenthesis */ - len = strlen(cp); - if (cp[len - 1] == ')') - cp[len - 1] = '\0'; - - /* Interpret the highlight (initialized to off above) */ - if (strcmp(cp, "on") == 0 || strncmp(cp, "on,", 3) == 0) - attrbuf[2] = 'b'; /* \Zb = enable bold (see dialog(1)) */ - -write_attrbuf: - sprintf(option->value.str, "%s", attrbuf); - - return (0); -} - -/* - * figpar call-back for interpreting value as .dialogrc `Boolean' - */ -static int -setbool(struct fp_config *option, uint32_t line __unused, - char *directive __unused, char *value) -{ - - if (option == NULL) { - warnx("%s:%d:%s: Missing callback parameter", __FILE__, - __LINE__, __func__); - return (-1); /* Abort processing */ - } - - /* Assume ON, check for OFF (case-insensitive) */ - option->value.boolean = 1; - strtolower(value); - if (strcmp(value, "off") == 0) - option->value.boolean = 0; - - return (0); -} - -/* - * figpar call-back for interpreting value as .dialogrc `Number' - */ -static int -setnum(struct fp_config *option, uint32_t line __unused, - char *directive __unused, char *value) -{ - - if (option == NULL) { - warnx("%s:%d:%s: Missing callback parameter", __FILE__, - __LINE__, __func__); - return (-1); /* Abort processing */ - } - - /* Convert the string to a 32-bit signed integer */ - option->value.num = (int32_t)strtol(value, (char **)NULL, 10); - - return (0); -} - -/* - * figpar call-back for interpreting value as .dialogrc `String' - */ -static int -setstr(struct fp_config *option, uint32_t line __unused, - char *directive __unused, char *value) -{ - size_t len; - - if (option == NULL) { - warnx("%s:%d:%s: Missing callback parameter", __FILE__, - __LINE__, __func__); - return (-1); /* Abort processing */ - } - - /* Allocate memory for the data if not already done */ - if (option->value.str == NULL) { - if ((option->value.str = malloc(STR_BUFSIZE)) == NULL) - return (-1); - } - - /* Trim leading quote */ - if (*value == '"') - value++; - - /* Write the data into the buffer */ - snprintf(option->value.str, STR_BUFSIZE, "%s", value); - - /* Trim trailing quote */ - len = strlen(option->value.str); - if (option->value.str[len - 1] == '"') - option->value.str[len - 1] = '\0'; - - return (0); -} - -/* - * Parse (in order of preference) $DIALOGRC or `$HOME/.dialogrc'. Returns zero - * on success, -1 on failure (and errno should be consulted). - */ -int -parse_dialogrc(void) -{ - char *cp; - int res; - size_t len; - char path[PATH_MAX]; - - /* Allow $DIALOGRC to override `$HOME/.dialogrc' default */ - if ((cp = getenv(ENV_DIALOGRC)) != NULL && *cp != '\0') - snprintf(path, PATH_MAX, "%s", cp); - else if ((cp = getenv(ENV_HOME)) != NULL) { - /* Copy $HOME into buffer and append trailing `/' if missing */ - snprintf(path, PATH_MAX, "%s", cp); - len = strlen(path); - cp = path + len; - if (len > 0 && len < (PATH_MAX - 1) && *(cp - 1) != '/') { - *cp++ = '/'; - *cp = '\0'; - len++; - } - - /* If we still have room, shove in the name of rc file */ - if (len < (PATH_MAX - 1)) - snprintf(cp, PATH_MAX - len, "%s", DIALOGRC); - } else { - /* Like dialog(1), don't process a file if $HOME is unset */ - errno = ENOENT; - return (-1); - } - - /* Process file (either $DIALOGRC if set, or `$HOME/.dialogrc') */ - res = parse_config(dialogrc_config, path, NULL, FP_BREAK_ON_EQUALS); - - /* Set some globals based on what we parsed */ - use_shadow = dialogrc_config_option("use_shadow")->value.boolean; - use_colors = dialogrc_config_option("use_colors")->value.boolean; - snprintf(gauge_color, STR_BUFSIZE, "%s", - dialogrc_config_option("gauge_color")->value.str); - - return (res); -} - -/* - * Return a pointer to the `.dialogrc' config option specific to `directive' or - * static fp_dummy_config (full of NULLs) if none found (see - * get_config_option(3); part of figpar(3)). - */ -struct fp_config * -dialogrc_config_option(const char *directive) -{ - return (get_config_option(dialogrc_config, directive)); -} - -/* - * Free allocated items initialized by setattr() (via parse_config() callback - * matrix [dialogrc_config] used in parse_dialogrc() above). - */ -void -dialogrc_free(void) -{ - char *value; - uint32_t n; - - for (n = 0; dialogrc_config[n].directive != NULL; n++) { - if (dialogrc_config[n].action != &setattr) - continue; - value = dialogrc_config[n].value.str; - if (value != NULL && value != gauge_color) { - free(dialogrc_config[n].value.str); - dialogrc_config[n].value.str = NULL; - } - } -} diff --git a/lib/libdpv/dialogrc.h b/lib/libdpv/dialogrc.h deleted file mode 100644 index 7d1723584..000000000 --- a/lib/libdpv/dialogrc.h +++ /dev/null @@ -1,56 +0,0 @@ -/*- - * Copyright (c) 2013-2014 Devin Teske - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * $FreeBSD$ - */ - -#ifndef _DIALOGRC_H_ -#define _DIALOGRC_H_ - -#include - -#include - -/* dialog(3) dlg_color_table[] attributes */ -#define GAUGE_ATTR 33 /* entry used for gauge_color */ - -/* dialog(1) characteristics */ -#define DIALOGRC ".dialogrc" -#define ENV_DIALOGRC "DIALOGRC" -#define ENV_HOME "HOME" - -/* dialog(1) `.dialogrc' characteristics */ -extern uint8_t use_colors; -extern uint8_t use_shadow; -extern char gauge_color[]; -extern char separator[]; - -__BEGIN_DECLS -void dialogrc_free(void); -int parse_dialogrc(void); -struct fp_config *dialogrc_config_option(const char *_directive); -__END_DECLS - -#endif /* !_DIALOGRC_H_ */ diff --git a/lib/libdpv/dprompt.c b/lib/libdpv/dprompt.c deleted file mode 100644 index 031f550e6..000000000 --- a/lib/libdpv/dprompt.c +++ /dev/null @@ -1,770 +0,0 @@ -/*- - * Copyright (c) 2013-2014 Devin Teske - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - */ - -#include -__FBSDID("$FreeBSD$"); - -#include - -#define _BSD_SOURCE /* to get dprintf() prototype in stdio.h below */ -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include "dialog_util.h" -#include "dialogrc.h" -#include "dprompt.h" -#include "dpv.h" -#include "dpv_private.h" - -#define FLABEL_MAX 1024 - -static int fheight = 0; /* initialized by dprompt_init() */ -static char dprompt[PROMPT_MAX + 1] = ""; -static char *dprompt_pos = (char *)(0); /* treated numerically */ - -/* Display characteristics */ -#define FM_DONE 0x01 -#define FM_FAIL 0x02 -#define FM_PEND 0x04 -static uint8_t dprompt_free_mask; -static char *done = NULL; -static char *fail = NULL; -static char *pend = NULL; -int display_limit = DISPLAY_LIMIT_DEFAULT; /* Max entries to show */ -int label_size = LABEL_SIZE_DEFAULT; /* Max width for labels */ -int pbar_size = PBAR_SIZE_DEFAULT; /* Mini-progressbar size */ -static int gauge_percent = 0; -static int done_size, done_lsize, done_rsize; -static int fail_size, fail_lsize, fail_rsize; -static int mesg_size, mesg_lsize, mesg_rsize; -static int pend_size, pend_lsize, pend_rsize; -static int pct_lsize, pct_rsize; -static void *gauge = NULL; -#define SPIN_SIZE 4 -static char spin[SPIN_SIZE + 1] = "/-\\|"; -static char msg[PROMPT_MAX + 1]; -static char *spin_cp = spin; - -/* Function prototypes */ -static char spin_char(void); -static int dprompt_add_files(struct dpv_file_node *file_list, - struct dpv_file_node *curfile, int pct); - -/* - * Returns a pointer to the current spin character in the spin string and - * advances the global position to the next character for the next call. - */ -static char -spin_char(void) -{ - char ch; - - if (spin_cp == '\0') - spin_cp = spin; - ch = *spin_cp; - - /* Advance the spinner to the next char */ - if (++spin_cp >= (spin + SPIN_SIZE)) - spin_cp = spin; - - return (ch); -} - -/* - * Initialize heights and widths based on various strings and environment - * variables (such as ENV_USE_COLOR). - */ -void -dprompt_init(struct dpv_file_node *file_list) -{ - uint8_t nls = 0; - int len; - int max_cols; - int max_rows; - int nthfile; - int numlines; - struct dpv_file_node *curfile; - - /* - * Initialize dialog(3) `colors' support and draw backtitle - */ - if (use_libdialog && !debug) { - init_dialog(stdin, stdout); - dialog_vars.colors = 1; - if (backtitle != NULL) { - dialog_vars.backtitle = (char *)backtitle; - dlg_put_backtitle(); - } - } - - /* Calculate width of dialog(3) or [X]dialog(1) --gauge box */ - dwidth = label_size + pbar_size + 9; - - /* - * Calculate height of dialog(3) or [X]dialog(1) --gauge box - */ - dheight = 5; - max_rows = dialog_maxrows(); - /* adjust max_rows for backtitle and/or dialog(3) statusLine */ - if (backtitle != NULL) - max_rows -= use_shadow ? 3 : 2; - if (use_libdialog && use_shadow) - max_rows -= 2; - /* add lines for `-p text' */ - numlines = dialog_prompt_numlines(pprompt, 0); - if (debug) - warnx("`-p text' is %i line%s long", numlines, - numlines == 1 ? "" : "s"); - dheight += numlines; - /* adjust dheight for various implementations */ - if (use_dialog) { - dheight -= dialog_prompt_nlstate(pprompt); - nls = dialog_prompt_nlstate(pprompt); - } else if (use_xdialog) { - if (pprompt == NULL || *pprompt == '\0') - dheight++; - } else if (use_libdialog) { - if (pprompt != NULL && *pprompt != '\0') - dheight--; - } - /* limit the number of display items (necessary per dialog(1,3)) */ - if (display_limit == 0 || display_limit > DPV_DISPLAY_LIMIT) - display_limit = DPV_DISPLAY_LIMIT; - /* verify fheight will fit (stop if we hit 1) */ - for (; display_limit > 0; display_limit--) { - nthfile = numlines = 0; - fheight = (int)dpv_nfiles > display_limit ? - (unsigned int)display_limit : dpv_nfiles; - for (curfile = file_list; curfile != NULL; - curfile = curfile->next) { - nthfile++; - numlines += dialog_prompt_numlines(curfile->name, nls); - if ((nthfile % display_limit) == 0) { - if (numlines > fheight) - fheight = numlines; - numlines = nthfile = 0; - } - } - if (numlines > fheight) - fheight = numlines; - if ((dheight + fheight + - (int)dialog_prompt_numlines(aprompt, use_dialog) - - (use_dialog ? (int)dialog_prompt_nlstate(aprompt) : 0)) - <= max_rows) - break; - } - /* don't show any items if we run the risk of hitting a blank set */ - if ((max_rows - (use_shadow ? 5 : 4)) >= fheight) - dheight += fheight; - else - fheight = 0; - /* add lines for `-a text' */ - numlines = dialog_prompt_numlines(aprompt, use_dialog); - if (debug) - warnx("`-a text' is %i line%s long", numlines, - numlines == 1 ? "" : "s"); - dheight += numlines; - - /* If using Xdialog(1), adjust accordingly (based on testing) */ - if (use_xdialog) - dheight += dheight / 4; - - /* For wide mode, long prefix (`pprompt') or append (`aprompt') - * strings will bump width */ - if (wide) { - len = (int)dialog_prompt_longestline(pprompt, 0); /* !nls */ - if ((len + 4) > dwidth) - dwidth = len + 4; - len = (int)dialog_prompt_longestline(aprompt, 1); /* nls */ - if ((len + 4) > dwidth) - dwidth = len + 4; - } - - /* Enforce width constraints to maximum values */ - max_cols = dialog_maxcols(); - if (max_cols > 0 && dwidth > max_cols) - dwidth = max_cols; - - /* Optimize widths to sane values*/ - if (pbar_size > dwidth - 9) { - pbar_size = dwidth - 9; - label_size = 0; - /* -9 = "| - [" ... "] |" */ - } - if (pbar_size < 0) - label_size = dwidth - 8; - /* -8 = "| " ... " - |" */ - else if (label_size > (dwidth - pbar_size - 9) || wide) - label_size = no_labels ? 0 : dwidth - pbar_size - 9; - /* -9 = "| " ... " - [" ... "] |" */ - - /* Hide labels if requested */ - if (no_labels) - label_size = 0; - - /* Touch up the height (now that we know dwidth) */ - dheight += dialog_prompt_wrappedlines(pprompt, dwidth - 4, 0); - dheight += dialog_prompt_wrappedlines(aprompt, dwidth - 4, 1); - - if (debug) - warnx("dheight = %i dwidth = %i fheight = %i", - dheight, dwidth, fheight); - - /* Calculate left/right portions of % */ - pct_lsize = (pbar_size - 4) / 2; /* -4 == printf("%-3s%%", pct) */ - pct_rsize = pct_lsize; - /* If not evenly divisible by 2, increment the right-side */ - if ((pct_rsize + pct_rsize + 4) != pbar_size) - pct_rsize++; - - /* Initialize "Done" text */ - if (done == NULL && (done = msg_done) == NULL) { - if ((done = getenv(ENV_MSG_DONE)) != NULL) - done_size = strlen(done); - else { - done_size = strlen(DPV_DONE_DEFAULT); - if ((done = malloc(done_size + 1)) == NULL) - errx(EXIT_FAILURE, "Out of memory?!"); - dprompt_free_mask |= FM_DONE; - snprintf(done, done_size + 1, DPV_DONE_DEFAULT); - } - } - if (pbar_size < done_size) { - done_lsize = done_rsize = 0; - *(done + pbar_size) = '\0'; - done_size = pbar_size; - } else { - /* Calculate left/right portions for mini-progressbar */ - done_lsize = (pbar_size - done_size) / 2; - done_rsize = done_lsize; - /* If not evenly divisible by 2, increment the right-side */ - if ((done_rsize + done_size + done_lsize) != pbar_size) - done_rsize++; - } - - /* Initialize "Fail" text */ - if (fail == NULL && (fail = msg_fail) == NULL) { - if ((fail = getenv(ENV_MSG_FAIL)) != NULL) - fail_size = strlen(fail); - else { - fail_size = strlen(DPV_FAIL_DEFAULT); - if ((fail = malloc(fail_size + 1)) == NULL) - errx(EXIT_FAILURE, "Out of memory?!"); - dprompt_free_mask |= FM_FAIL; - snprintf(fail, fail_size + 1, DPV_FAIL_DEFAULT); - } - } - if (pbar_size < fail_size) { - fail_lsize = fail_rsize = 0; - *(fail + pbar_size) = '\0'; - fail_size = pbar_size; - } else { - /* Calculate left/right portions for mini-progressbar */ - fail_lsize = (pbar_size - fail_size) / 2; - fail_rsize = fail_lsize; - /* If not evenly divisible by 2, increment the right-side */ - if ((fail_rsize + fail_size + fail_lsize) != pbar_size) - fail_rsize++; - } - - /* Initialize "Pending" text */ - if (pend == NULL && (pend = msg_pending) == NULL) { - if ((pend = getenv(ENV_MSG_PENDING)) != NULL) - pend_size = strlen(pend); - else { - pend_size = strlen(DPV_PENDING_DEFAULT); - if ((pend = malloc(pend_size + 1)) == NULL) - errx(EXIT_FAILURE, "Out of memory?!"); - dprompt_free_mask |= FM_PEND; - snprintf(pend, pend_size + 1, DPV_PENDING_DEFAULT); - } - } - if (pbar_size < pend_size) { - pend_lsize = pend_rsize = 0; - *(pend + pbar_size) = '\0'; - pend_size = pbar_size; - } else { - /* Calculate left/right portions for mini-progressbar */ - pend_lsize = (pbar_size - pend_size) / 2; - pend_rsize = pend_lsize; - /* If not evenly divisible by 2, increment the right-side */ - if ((pend_rsize + pend_lsize + pend_size) != pbar_size) - pend_rsize++; - } - - if (debug) - warnx("label_size = %i pbar_size = %i", label_size, pbar_size); - - dprompt_clear(); -} - -/* - * Clear the [X]dialog(1) `--gauge' prompt buffer. - */ -void -dprompt_clear(void) -{ - - *dprompt = '\0'; - dprompt_pos = dprompt; -} - -/* - * Append to the [X]dialog(1) `--gauge' prompt buffer. Syntax is like printf(3) - * and returns the number of bytes appended to the buffer. - */ -int -dprompt_add(const char *format, ...) -{ - int len; - va_list ap; - - if (dprompt_pos >= (dprompt + PROMPT_MAX)) - return (0); - - va_start(ap, format); - len = vsnprintf(dprompt_pos, (size_t)(PROMPT_MAX - - (dprompt_pos - dprompt)), format, ap); - va_end(ap); - if (len == -1) - errx(EXIT_FAILURE, "%s: Oops, dprompt buffer overflow", - __func__); - - if ((dprompt_pos + len) < (dprompt + PROMPT_MAX)) - dprompt_pos += len; - else - dprompt_pos = dprompt + PROMPT_MAX; - - return (len); -} - -/* - * Append active files to the [X]dialog(1) `--gauge' prompt buffer. Syntax - * requires a pointer to the head of the dpv_file_node linked-list. Returns the - * number of files processed successfully. - */ -static int -dprompt_add_files(struct dpv_file_node *file_list, - struct dpv_file_node *curfile, int pct) -{ - char c; - char bold_code = 'b'; /* default: enabled */ - char color_code = '4'; /* default: blue */ - uint8_t after_curfile = curfile != NULL ? FALSE : TRUE; - uint8_t nls = 0; - char *cp; - char *lastline; - char *name; - const char *bg_code; - const char *estext; - const char *format; - enum dprompt_state dstate; - int estext_lsize; - int estext_rsize; - int estext_size; - int flabel_size; - int hlen; - int lsize; - int nlines = 0; - int nthfile = 0; - int pwidth; - int rsize; - struct dpv_file_node *fp; - char flabel[FLABEL_MAX + 1]; - char human[32]; - char pbar[pbar_size + 16]; /* +15 for optional color */ - char pbar_cap[sizeof(pbar)]; - char pbar_fill[sizeof(pbar)]; - - - /* Override color defaults with that of main progress bar */ - if (use_colors || use_shadow) { /* NB: shadow enables color */ - color_code = gauge_color[0]; - /* NB: str[1] aka bg is unused */ - bold_code = gauge_color[2]; - } - - /* - * Create mini-progressbar for current file (if applicable) - */ - *pbar = '\0'; - if (pbar_size >= 0 && pct >= 0 && curfile != NULL && - (curfile->length >= 0 || dialog_test)) { - snprintf(pbar, pbar_size + 1, "%*s%3u%%%*s", pct_lsize, "", - pct, pct_rsize, ""); - if (use_color) { - /* Calculate the fill-width of progressbar */ - pwidth = pct * pbar_size / 100; - /* Round up based on one-tenth of a percent */ - if ((pct * pbar_size % 100) > 50) - pwidth++; - - /* - * Make two copies of pbar. Make one represent the fill - * and the other the remainder (cap). We'll insert the - * ANSI delimiter in between. - */ - *pbar_fill = '\0'; - *pbar_cap = '\0'; - strncat(pbar_fill, (const char *)(pbar), dwidth); - *(pbar_fill + pwidth) = '\0'; - strncat(pbar_cap, (const char *)(pbar+pwidth), dwidth); - - /* Finalize the mini [color] progressbar */ - snprintf(pbar, sizeof(pbar), - "\\Z%c\\Zr\\Z%c%s%s%s\\Zn", bold_code, color_code, - pbar_fill, "\\ZR", pbar_cap); - } - } - - for (fp = file_list; fp != NULL; fp = fp->next) { - flabel_size = label_size; - name = fp->name; - nthfile++; - - /* - * Support multiline filenames (where the filename is taken as - * the last line and the text leading up to the last line can - * be used as (for example) a heading/separator between files. - */ - if (use_dialog) - nls = dialog_prompt_nlstate(pprompt); - nlines += dialog_prompt_numlines(name, nls); - lastline = dialog_prompt_lastline(name, 1); - if (name != lastline) { - c = *lastline; - *lastline = '\0'; - dprompt_add("%s", name); - *lastline = c; - name = lastline; - } - - /* Support color codes (for dialog(1,3)) in file names */ - if ((use_dialog || use_libdialog) && use_color) { - cp = name; - while (*cp != '\0') { - if (*cp == '\\' && *(cp + 1) != '\0' && - *(++cp) == 'Z' && *(cp + 1) != '\0') { - cp++; - flabel_size += 3; - } - cp++; - } - if (flabel_size > FLABEL_MAX) - flabel_size = FLABEL_MAX; - } - - /* If no mini-progressbar, increase label width */ - if (pbar_size < 0 && flabel_size <= FLABEL_MAX - 2 && - no_labels == FALSE) - flabel_size += 2; - - /* If name is too long, add an ellipsis */ - if (snprintf(flabel, flabel_size + 1, "%s", name) > - flabel_size) sprintf(flabel + flabel_size - 3, "..."); - - /* - * Append the label (processing the current file differently) - */ - if (fp == curfile && pct < 100) { - /* - * Add an ellipsis to current file name if it will fit. - * There may be an ellipsis already from truncating the - * label (in which case, we already have one). - */ - cp = flabel + strlen(flabel); - if (cp < (flabel + flabel_size)) - snprintf(cp, flabel_size - - (cp - flabel) + 1, "..."); - - /* Append label (with spinner and optional color) */ - dprompt_add("%s%-*s%s %c", use_color ? "\\Zb" : "", - flabel_size, flabel, use_color ? "\\Zn" : "", - spin_char()); - } else - dprompt_add("%-*s%s %s", flabel_size, - flabel, use_color ? "\\Zn" : "", " "); - - /* - * Append pbar/status (processing the current file differently) - */ - dstate = DPROMPT_NONE; - if (fp->msg != NULL) - dstate = DPROMPT_CUSTOM_MSG; - else if (pbar_size < 0) - dstate = DPROMPT_NONE; - else if (pbar_size < 4) - dstate = DPROMPT_MINIMAL; - else if (after_curfile) - dstate = DPROMPT_PENDING; - else if (fp == curfile) { - if (*pbar == '\0') { - if (fp->length < 0) - dstate = DPROMPT_DETAILS; - else if (fp->status == DPV_STATUS_RUNNING) - dstate = DPROMPT_DETAILS; - else - dstate = DPROMPT_END_STATE; - } - else if (dialog_test) /* status/length ignored */ - dstate = pct < 100 ? - DPROMPT_PBAR : DPROMPT_END_STATE; - else if (fp->status == DPV_STATUS_RUNNING) - dstate = fp->length < 0 ? - DPROMPT_DETAILS : DPROMPT_PBAR; - else /* not running */ - dstate = fp->length < 0 ? - DPROMPT_DETAILS : DPROMPT_END_STATE; - } else { /* before curfile */ - if (dialog_test) - dstate = DPROMPT_END_STATE; - else - dstate = fp->length < 0 ? - DPROMPT_DETAILS : DPROMPT_END_STATE; - } - format = use_color ? - " [\\Z%c%s%-*s%s%-*s\\Zn]\\n" : - " [%-*s%s%-*s]\\n"; - if (fp->status == DPV_STATUS_FAILED) { - bg_code = "\\Zr\\Z1"; /* Red */ - estext_lsize = fail_lsize; - estext_rsize = fail_rsize; - estext_size = fail_size; - estext = fail; - } else { /* e.g., DPV_STATUS_DONE */ - bg_code = "\\Zr\\Z2"; /* Green */ - estext_lsize = done_lsize; - estext_rsize = done_rsize; - estext_size = done_size; - estext = done; - } - switch (dstate) { - case DPROMPT_PENDING: /* Future file(s) */ - dprompt_add(" [%-*s%s%-*s]\\n", - pend_lsize, "", pend, pend_rsize, ""); - break; - case DPROMPT_PBAR: /* Current file */ - dprompt_add(" [%s]\\n", pbar); - break; - case DPROMPT_END_STATE: /* Past/Current file(s) */ - if (use_color) - dprompt_add(format, bold_code, bg_code, - estext_lsize, "", estext, - estext_rsize, ""); - else - dprompt_add(format, - estext_lsize, "", estext, - estext_rsize, ""); - break; - case DPROMPT_DETAILS: /* Past/Current file(s) */ - humanize_number(human, pbar_size + 2, fp->read, "", - HN_AUTOSCALE, HN_NOSPACE | HN_DIVISOR_1000); - - /* Calculate center alignment */ - hlen = (int)strlen(human); - lsize = (pbar_size - hlen) / 2; - rsize = lsize; - if ((lsize+hlen+rsize) != pbar_size) - rsize++; - - if (use_color) - dprompt_add(format, bold_code, bg_code, - lsize, "", human, rsize, ""); - else - dprompt_add(format, - lsize, "", human, rsize, ""); - break; - case DPROMPT_CUSTOM_MSG: /* File-specific message override */ - snprintf(msg, PROMPT_MAX + 1, "%s", fp->msg); - if (pbar_size < (mesg_size = strlen(msg))) { - mesg_lsize = mesg_rsize = 0; - *(msg + pbar_size) = '\0'; - mesg_size = pbar_size; - } else { - mesg_lsize = (pbar_size - mesg_size) / 2; - mesg_rsize = mesg_lsize; - if ((mesg_rsize + mesg_size + mesg_lsize) - != pbar_size) - mesg_rsize++; - } - if (use_color) - dprompt_add(format, bold_code, bg_code, - mesg_lsize, "", msg, mesg_rsize, ""); - else - dprompt_add(format, mesg_lsize, "", msg, - mesg_rsize, ""); - break; - case DPROMPT_MINIMAL: /* Short progress bar, minimal room */ - if (use_color) - dprompt_add(format, bold_code, bg_code, - pbar_size, "", "", 0, ""); - else - dprompt_add(format, pbar_size, "", "", 0, ""); - break; - case DPROMPT_NONE: /* pbar_size < 0 */ - /* FALLTHROUGH */ - default: - dprompt_add(" \\n"); - /* - * NB: Leading space required for the case when - * spin_char() returns a single backslash [\] which - * without the space, changes the meaning of `\n' - */ - } - - /* Stop building if we've hit the internal limit */ - if (nthfile >= display_limit) - break; - - /* If this is the current file, all others are pending */ - if (fp == curfile) - after_curfile = TRUE; - } - - /* - * Since we cannot change the height/width of the [X]dialog(1) widget - * after spawn, to make things look nice let's pad the height so that - * the `-a text' always appears in the same spot. - * - * NOTE: fheight is calculated in dprompt_init(). It represents the - * maximum height required to display the set of items (broken up into - * pieces of display_limit chunks) whose names contain the most - * newlines for any given set. - */ - while (nlines < fheight) { - dprompt_add("\n"); - nlines++; - } - - return (nthfile); -} - -/* - * Process the dpv_file_node linked-list of named files, re-generating the - * [X]dialog(1) `--gauge' prompt text for the current state of transfers. - */ -void -dprompt_recreate(struct dpv_file_node *file_list, - struct dpv_file_node *curfile, int pct) -{ - size_t len; - - /* - * Re-Build the prompt text - */ - dprompt_clear(); - if (display_limit > 0) - dprompt_add_files(file_list, curfile, pct); - - /* Xdialog(1) requires newlines (a) escaped and (b) in triplicate */ - if (use_xdialog) { - /* Replace `\n' with `\n\\n\n' in dprompt */ - len = strlen(dprompt); - len += strcount(dprompt, "\\n") * 5; /* +5 chars per count */ - if (len > PROMPT_MAX) - errx(EXIT_FAILURE, "%s: Oops, dprompt buffer overflow " - "(%zu > %i)", __func__, len, PROMPT_MAX); - if (replaceall(dprompt, "\\n", "\n\\n\n") < 0) - err(EXIT_FAILURE, "%s: replaceall()", __func__); - } - else if (use_libdialog) - strexpandnl(dprompt); -} - -/* - * Print the [X]dialog(1) `--gauge' prompt text to a buffer. - */ -int -dprompt_sprint(char * restrict str, const char *prefix, const char *append) -{ - - return (snprintf(str, PROMPT_MAX, "%s%s%s%s", use_color ? "\\Zn" : "", - prefix ? prefix : "", dprompt, append ? append : "")); -} - -/* - * Print the [X]dialog(1) `--gauge' prompt text to file descriptor fd (could - * be STDOUT_FILENO or a pipe(2) file descriptor to actual [X]dialog(1)). - */ -void -dprompt_dprint(int fd, const char *prefix, const char *append, int overall) -{ - int percent = gauge_percent; - - if (overall >= 0 && overall <= 100) - gauge_percent = percent = overall; - dprintf(fd, "XXX\n%s%s%s%s\nXXX\n%i\n", use_color ? "\\Zn" : "", - prefix ? prefix : "", dprompt, append ? append : "", percent); - fsync(fd); -} - -/* - * Print the dialog(3) `gauge' prompt text using libdialog. - */ -void -dprompt_libprint(const char *prefix, const char *append, int overall) -{ - int percent = gauge_percent; - char buf[DPV_PPROMPT_MAX + DPV_APROMPT_MAX + DPV_DISPLAY_LIMIT * 1024]; - - dprompt_sprint(buf, prefix, append); - - if (overall >= 0 && overall <= 100) - gauge_percent = percent = overall; - gauge = dlg_reallocate_gauge(gauge, title == NULL ? "" : title, - buf, dheight, dwidth, percent); - dlg_update_gauge(gauge, percent); -} - -/* - * Free allocated items initialized by dprompt_init() - */ -void -dprompt_free(void) -{ - if ((dprompt_free_mask & FM_DONE) != 0) { - dprompt_free_mask ^= FM_DONE; - free(done); - done = NULL; - } - if ((dprompt_free_mask & FM_FAIL) != 0) { - dprompt_free_mask ^= FM_FAIL; - free(fail); - fail = NULL; - } - if ((dprompt_free_mask & FM_PEND) != 0) { - dprompt_free_mask ^= FM_PEND; - free(pend); - pend = NULL; - } -} diff --git a/lib/libdpv/dprompt.h b/lib/libdpv/dprompt.h deleted file mode 100644 index a082364fa..000000000 --- a/lib/libdpv/dprompt.h +++ /dev/null @@ -1,59 +0,0 @@ -/*- - * Copyright (c) 2013-2014 Devin Teske - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * $FreeBSD$ - */ - -#ifndef _DPROMPT_H_ -#define _DPROMPT_H_ - -#include - -#include "dpv.h" - -/* Display characteristics */ -#define ENV_MSG_DONE "msg_done" -#define ENV_MSG_FAIL "msg_fail" -#define ENV_MSG_PENDING "msg_pending" -extern int display_limit; -extern int label_size; -extern int pbar_size; - -__BEGIN_DECLS -void dprompt_clear(void); -void dprompt_dprint(int _fd, const char *_prefix, const char *_append, - int _overall); -void dprompt_free(void); -void dprompt_init(struct dpv_file_node *_file_list); -void dprompt_libprint(const char *_prefix, const char *_append, - int _overall); -void dprompt_recreate(struct dpv_file_node *_file_list, - struct dpv_file_node *_curfile, int _pct); -int dprompt_add(const char *_format, ...); -int dprompt_sprint(char * restrict _str, const char *_prefix, - const char *_append); -__END_DECLS - -#endif /* !_DPROMPT_H_ */ diff --git a/lib/libdpv/dpv.3 b/lib/libdpv/dpv.3 deleted file mode 100644 index 8c04ac31c..000000000 --- a/lib/libdpv/dpv.3 +++ /dev/null @@ -1,510 +0,0 @@ -.\" Copyright (c) 2013-2014 Devin Teske -.\" All rights reserved. -.\" -.\" Redistribution and use in source and binary forms, with or without -.\" modification, are permitted provided that the following conditions -.\" are met: -.\" 1. Redistributions of source code must retain the above copyright -.\" notice, this list of conditions and the following disclaimer. -.\" 2. Redistributions in binary form must reproduce the above copyright -.\" notice, this list of conditions and the following disclaimer in the -.\" documentation and/or other materials provided with the distribution. -.\" -.\" THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND -.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE -.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE -.\" ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE -.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL -.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS -.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) -.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT -.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY -.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF -.\" SUCH DAMAGE. -.\" -.\" $FreeBSD$ -.\" -.Dd Oct 24, 2014 -.Dt DPV 3 -.Os -.Sh NAME -.Nm dpv -.Nd dialog progress view library -.Sh LIBRARY -.Lb libdpv -.Sh SYNOPSIS -.In dpv.h -.Ft int -.Fo dpv -.Fa "struct dpv_config *config, struct dpv_file_node *file_list" -.Fc -.Ft void -.Fo dpv_free -.Fa "void" -.Fc -.Sh DESCRIPTION -The -.Nm -library provides an interface for creating complex -.Dq gauge -widgets for displaying progress on various actions. -The -.Nm -library can display progress with one of -.Xr dialog 3 , -.Xr dialog 1 , -or -.Xr Xdialog 1 -.Pq x11/xdialog from the ports tree . -.Pp -The -.Fn dpv -.Fa config -argument contains the following properties for configuring global display -features: -.Bd -literal -offset indent -struct dpv_config { - enum dpv_display display_type; /* Def. DPV_DISPLAY_LIBDIALOG */ - enum dpv_output output_type; /* Default DPV_OUTPUT_NONE */ - int debug; /* Enable debug on stderr */ - int display_limit; /* Files/page. Default -1 */ - int label_size; /* Label size. Default 28 */ - int pbar_size; /* Mini-progress size */ - int dialog_updates_per_second; /* Default 16 */ - int status_updates_per_second; /* Default 2 */ - uint16_t options; /* Default 0 (none) */ - char *title; /* Widget title */ - char *backtitle; /* Widget backtitle */ - char *aprompt; /* Append. Default NULL */ - char *pprompt; /* Prefix. Default NULL */ - char *msg_done; /* Default `Done' */ - char *msg_fail; /* Default `Fail' */ - char *msg_pending; /* Default `Pending' */ - char *output; /* Output format string */ - const char *status_solo; /* dialog(3) solo-status format. - * Default DPV_STATUS_SOLO */ - const char *status_many; /* dialog(3) many-status format. - * Default DPV_STATUS_MANY */ - - /* - * Function pointer; action to perform data transfer - */ - int (*action)(struct dpv_file_node *file, int out); -}; - -enum dpv_display { - DPV_DISPLAY_LIBDIALOG = 0, /* Use dialog(3) (default) */ - DPV_DISPLAY_STDOUT, /* Use stdout */ - DPV_DISPLAY_DIALOG, /* Use spawned dialog(1) */ - DPV_DISPLAY_XDIALOG, /* Use spawned Xdialog(1) */ -}; - -enum dpv_output { - DPV_OUTPUT_NONE = 0, /* No output (default) */ - DPV_OUTPUT_FILE, /* Read `output' member as file path */ - DPV_OUTPUT_SHELL, /* Read `output' member as shell cmd */ -}; -.Ed -.Pp -The -.Va options -member of the -.Fn dpv -.Fa config -argument is a mask of bit fields indicating various processing options. -Possible flags are as follows: -.Bl -tag -width DPV_NO_OVERRUN -.It Dv DPV_TEST_MODE -Enable test mode. -In test mode, the -.Fn action -callback of the -.Fa config -argument is not called but instead simulated-data is used to drive progress. -Appends -.Dq [TEST MODE] -to the status line -.Po -to override, set the -.Va status_format -member of the -.Fn dpv -.Fa config -argument; -e.g., to -.Dv DPV_STATUS_DEFAULT -.Pc . -.It Dv DPV_WIDE_MODE -Enable wide mode. -In wide mode, the length of the -.Va aprompt -and -.Va pprompt -members of the -.Fn dpv -.Fa config -argument will bump the width of the gauge widget. -Prompts wider than the maximum width will wrap -.Po -unless using -.Xr Xdialog 1 ; -see BUGS section below -.Pc . -.It Dv DPV_NO_LABELS -Disables the display of labels associated with each transfer -.Po -.Va label_size -member of -.Fn dpv -.Fa config -argument is ignored -.Pc . -.It Dv DPV_USE_COLOR -Force the use of color even if the -.Va display_type -does not support color -.Po -.Ev USE_COLOR -environment variable is ignored -.Pc . -.It Dv DPV_NO_OVERRUN -When enabled, callbacks for the current -.Vt dpv_file_node -are terminated when -.Fn action -returns 100 or greater -.Po -alleviates the need to change the -.Va status -of the current -.Vt dpv_file_node -but may also cause file truncation if the stream exceeds expected length -.Pc . -.El -.Pp -The -.Fa file_list -argument to -.Fn dpv -is a pointer to a -.Dq linked-list , -described as follows in -.In dpv.h : -.Bd -literal -offset indent -struct dpv_file_node { - enum dpv_status status; /* status of read operation */ - char *msg; /* display instead of "Done/Fail" */ - char *name; /* name of file to read */ - char *path; /* path to file */ - long long length; /* expected size */ - long long read; /* number units read (e.g., bytes) */ - struct dpv_file_node *next;/* pointer to next (end with NULL) */ -}; -.Ed -.Pp -For each of the items in the -.Fa file_list -.Dq linked-list -argument, the -.Fn action -callback member of the -.Fn dpv -.Fa config -argument is called. -The -.Fn action -function should perform a -.Dq nominal -action on the file and return. -The return value of -.Vt int -represents the current progress percentage -.Pq 0-100 -for the current file. -.Pp -The -.Fn action -callback provides two variables for each call. -.Fa file -provides a reference to the current -.Vt dpv_file_node -being processed. -.Fa out -provides a file descriptor where the data should go. -.Pp -If the -.Va output -member of the -.Fn dpv -.Fa config -argument was set to DPV_OUTPUT_NONE -.Pq default ; when invoking Fn dpv , -the -.Fa out -file descriptor of -.Fn action -will be zero and should be ignored. -If -.Fa output -was set to DPV_OUTPUT_FILE, -.Fa out -will be an open file descriptor to a file. -If -.Fa output -was set to DPV_OUTPUT_SHELL, -.Fa out -will be an open file descriptor to a pipe for a spawned shell program. -When -.Fa out -is greater than zero, you should write any data you have read back to -.Fa out . -.Pp -To abort -.Fn dpv , -either from the -.Fn action -callback or asynchronously from a signal handler, two globals are provided via -.In dpv.h : -.Bd -literal -offset indent -extern int dpv_interrupt; /* Set to TRUE in interrupt handler */ -extern int dpv_abort; /* Set to true in callback to abort */ -.Ed -.Pp -These globals are not automatically reset and must be manually maintained. -Don't forget to reset these globals before subsequent invocations of -.Fn dpv -when making multiple calls from the same program. -.Pp -In addition, the -.Va status -member of the -.Fn action -.Fa file -argument can be used to control callbacks for the current file. -The -.Va status -member can be set to any of the following from -.In dpv.h : -.Bd -literal -offset indent -enum dpv_status { - DPV_STATUS_RUNNING = 0, /* Running (default) */ - DPV_STATUS_DONE, /* Completed */ - DPV_STATUS_FAILED, /* Oops, something went wrong */ -}; -.Ed -.Pp -The default -.Fa status -is zero, DPV_STATUS_RUNING, which keeps the callbacks coming for the current -.Fn file . -Setting -.Ql file->status -to anything other than DPV_STATUS_RUNNING will cause -.Fn dpv -to loop to the next file, effecting the next callback, if any. -.Pp -The -.Fn action -callback is responsible for calculating percentages and -.Pq recommended -maintaining a -.Nm -global counter so -.Fn dpv -can display throughput statistics. -Percentages are reported through the -.Vt int -return value of the -.Fn action -callback. -Throughput statistics are calculated from the following global -.Vt int -in -.In dpv.h : -.Bd -literal -offset indent -extern int dpv_overall_read; -.Ed -.Pp -This should be set to the number of bytes that have been read for all files. -Throughput information is displayed in the status line -.Pq only available when using Xr dialog 3 -at the bottom of the screen. -See DPV_DISPLAY_LIBDIALOG above. -.Pp -Note that -.Va dpv_overall_read -does not have to represent bytes. -For example, you can change the -.Va status_format -to display something other than -.Dq Li bytes -and increment -.Va dpv_overall_read -accordingly -.Pq e.g., counting lines . -.Pp -When -.Fn dpv -is processing the current file, the -.Va length -and -.Va read -members of the -.Fn action -.Fa file -argument are used for calculating the display of mini progress bars -.Po -if enabled; see -.Va pbar_size -above -.Pc . -If the -.Va length -member of the current -.Fa file -is less than zero -.Pq indicating an unknown file length , -a -.Xr humanize_number 3 -version of the -.Va read -member is used instead of a traditional progress bar. -Otherwise a progress bar is calculated as percentage read to file length. -.Fn action -callback must maintain these member values for mini-progress bars. -.Pp -The -.Fn dpv_free -function performs -.Xr free 3 -on private global variables initialized by -.Fn dpv . -.Sh ENVIRONMENT -The following environment variables are referenced by -.Nm : -.Bl -tag -width ".Ev USE_COLOR" -.It Ev DIALOG -Override command string used to launch -.Xr dialog 1 -.Pq requires Dv DPV_DISPLAY_DIALOG -or -.Xr Xdialog 1 -.Pq requires Dv DPV_DISPLAY_XDIALOG ; -default is either -.Ql dialog -.Pq for Dv DPV_DISPLAY_DIALOG -or -.Ql Xdialog -.Pq for Dv DPV_DISPLAY_XDIALOG . -.It Ev DIALOGRC -If set and non-NULL, path to -.Ql .dialogrc -file. -.It Ev HOME -If -.Ql Ev $DIALOGRC -is either not set or NULL, used as a prefix to -.Ql .dialogrc -.Pq i.e., Ql $HOME/.dialogrc . -.It Ev USE_COLOR -If set and NULL, disables the use of color when using -.Xr dialog 1 -.Pq does not apply to Xr Xdialog 1 . -.It Ev msg_done Ev msg_fail Ev msg_pending -Internationalization strings for overriding the default English strings -.Ql Done , -.Ql Fail , -and -.Ql Pending -respectively. -To prevent their usage, explicitly set the -.Va msg_done , -.Va msg_fail , -and -.Va msg_pending -members of -.Fn dpv -.Fa config -argument to default macros -.Pq DPV_DONE_DEFAULT, DPV_FAIL_DEFAULT, and DPV_PENDING_DEFAULT -or desired values. -.El -.Sh FILES -.Bl -tag -width ".Pa $HOME/.dialogrc" -compact -.It Pa $HOME/.dialogrc -.El -.Sh SEE ALSO -.Xr dialog 1 , -.Xr dialog 3 , -.Xr Xdialog 1 -.Sh HISTORY -The -.Nm -library first appeared in -.Fx 11.0 . -.Sh AUTHORS -.An Devin Teske Aq dteske@FreeBSD.org -.Sh BUGS -.Xr Xdialog 1 , -when given both -.Ql Fl -title Ar title -.Po -see above -.Ql Va title -member of -.Va struct dpv_config -.Pc -and -.Ql Fl -backtitle Ar backtitle -.Po -see above -.Ql Va backtitle -member of -.Va struct dpv_config -.Pc , -displays the backtitle in place of the title and vice-versa. -.Pp -.Xr Xdialog 1 -does not wrap long prompt texts received after initial launch. -This is a known issue with the -.Ql --gauge -widget in -.Xr Xdialog 1 . -Embed escaped newlines within prompt text(s) to force line breaks. -.Pp -.Xr dialog 1 -does not display the first character after a series of escaped escape-sequences -(e.g., ``\\\\n'' produces ``\\'' instead of ``\\n''). -This is a known issue with -.Xr dialog 1 -and does not affect -.Xr dialog 3 -or -.Xr Xdialog 1 . -.Pp -If your application ignores -.Ev USE_COLOR -when set and NULL before calling -.Xr dpv 3 -with color escape sequences anyway, -.Xr dialog 3 -and -.Xr dialog 1 -may not render properly. -Workaround is to detect when -.Ev USE_COLOR -is set and NULL and either not use color escape sequences at that time or use -.Xr unsetenv 3 -to unset -.Ev USE_COLOR , -forcing interpretation of color sequences. -This does not effect -.Xr Xdialog 1 , -which renders the color escape sequences as plain text. -See -.Do Li -embedded "\\Z" sequences -.Dc -in -.Xr dialog 1 -for additional information. diff --git a/lib/libdpv/dpv.c b/lib/libdpv/dpv.c deleted file mode 100644 index fd443608e..000000000 --- a/lib/libdpv/dpv.c +++ /dev/null @@ -1,721 +0,0 @@ -/*- - * Copyright (c) 2013-2014 Devin Teske - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - */ - -#include -__FBSDID("$FreeBSD$"); - -#include -#include -#include -#include - -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include "dialog_util.h" -#include "dialogrc.h" -#include "dprompt.h" -#include "dpv.h" -#include "dpv_private.h" -#include "status.h" -#include "util.h" - -/* Test Mechanics (Only used when dpv_config.options |= DPV_TEST_MODE) */ -#define INCREMENT 1 /* Increment % per-pass test-mode */ -#define XDIALOG_INCREMENT 15 /* different for slower Xdialog(1) */ -static uint8_t increment = INCREMENT; - -/* Debugging */ -uint8_t debug = FALSE; - -/* Data to process */ -int dpv_interrupt = FALSE; -int dpv_abort = FALSE; -unsigned int dpv_nfiles = 0; - -/* Data processing */ -long long dpv_overall_read = 0; -static char pathbuf[PATH_MAX]; - -/* Extra display information */ -uint8_t no_labels = FALSE; /* dpv_config.options & DPV_NO_LABELS */ -uint8_t wide = FALSE; /* dpv_config.options & DPV_WIDE_MODE */ -char *aprompt = NULL; /* dpv_config.aprompt */ -char *msg_done = NULL; /* dpv_config.msg_done */ -char *msg_fail = NULL; /* dpv_config.msg_fail */ -char *msg_pending = NULL; /* dpv_config.msg_pending */ -char *pprompt = NULL; /* dpv_config.pprompt */ - -/* Status-Line format for when using dialog(3) */ -static const char *status_format_custom = NULL; -static char status_format_default[DPV_STATUS_FORMAT_MAX]; - -/* - * Takes a pointer to a dpv_config structure containing layout details and - * pointer to initial element in a linked-list of dpv_file_node structures, - * each presenting a file to process. Executes the `action' function passed-in - * as a member to the `config' structure argument. - */ -int -dpv(struct dpv_config *config, struct dpv_file_node *file_list) -{ - char c; - uint8_t keep_going; - uint8_t nls = FALSE; /* See dialog_prompt_nlstate() */ - uint8_t no_overrun = FALSE; - uint8_t pprompt_nls = FALSE; /* See dialog_prompt_nlstate() */ - uint8_t shrink_label_size = FALSE; - mode_t mask; - uint16_t options; - char *cp; - char *fc; - char *last; - char *name; - char *output; - const char *status_fmt; - const char *path_fmt; - enum dpv_display display_type; - enum dpv_output output_type; - enum dpv_status status; - int (*action)(struct dpv_file_node *file, int out); - int backslash; - int dialog_last_update = 0; - int dialog_old_nthfile = 0; - int dialog_old_seconds = -1; - int dialog_out = STDOUT_FILENO; - int dialog_update_usec = 0; - int dialog_updates_per_second; - int files_left; - int max_cols; - int nthfile = 0; - int output_out; - int overall = 0; - int pct; - int res; - int seconds; - int status_last_update = 0; - int status_old_nthfile = 0; - int status_old_seconds = -1; - int status_update_usec = 0; - int status_updates_per_second; - pid_t output_pid; - pid_t pid; - size_t len; - struct dpv_file_node *curfile; - struct dpv_file_node *first_file; - struct dpv_file_node *list_head; - struct timeval now; - struct timeval start; - char init_prompt[PROMPT_MAX + 1] = ""; - - /* Initialize globals to default values */ - aprompt = NULL; - pprompt = NULL; - options = 0; - action = NULL; - backtitle = NULL; - debug = FALSE; - dialog_test = FALSE; - dialog_updates_per_second = DIALOG_UPDATES_PER_SEC; - display_limit = DISPLAY_LIMIT_DEFAULT; - display_type = DPV_DISPLAY_LIBDIALOG; - label_size = LABEL_SIZE_DEFAULT; - msg_done = NULL; - msg_fail = NULL; - msg_pending = NULL; - no_labels = FALSE; - output = NULL; - output_type = DPV_OUTPUT_NONE; - pbar_size = PBAR_SIZE_DEFAULT; - status_format_custom = NULL; - status_updates_per_second = STATUS_UPDATES_PER_SEC; - title = NULL; - wide = FALSE; - - /* Process config options (overriding defaults) */ - if (config != NULL) { - if (config->aprompt != NULL) { - if (aprompt == NULL) { - aprompt = malloc(DPV_APROMPT_MAX); - if (aprompt == NULL) - return (-1); - } - snprintf(aprompt, DPV_APROMPT_MAX, "%s", - config->aprompt); - } - if (config->pprompt != NULL) { - if (pprompt == NULL) { - pprompt = malloc(DPV_PPROMPT_MAX + 2); - /* +2 is for implicit "\n" appended later */ - if (pprompt == NULL) - return (-1); - } - snprintf(pprompt, DPV_APROMPT_MAX, "%s", - config->pprompt); - } - - options = config->options; - action = config->action; - backtitle = config->backtitle; - debug = config->debug; - dialog_test = ((options & DPV_TEST_MODE) != 0); - dialog_updates_per_second = config->dialog_updates_per_second; - display_limit = config->display_limit; - display_type = config->display_type; - label_size = config->label_size; - msg_done = (char *)config->msg_done; - msg_fail = (char *)config->msg_fail; - msg_pending = (char *)config->msg_pending; - no_labels = ((options & DPV_NO_LABELS) != 0); - no_overrun = ((options & DPV_NO_OVERRUN) != 0); - output = config->output; - output_type = config->output_type; - pbar_size = config->pbar_size; - status_updates_per_second = config->status_updates_per_second; - title = config->title; - wide = ((options & DPV_WIDE_MODE) != 0); - - /* Enforce some minimums (pedantic) */ - if (display_limit < -1) - display_limit = -1; - if (label_size < -1) - label_size = -1; - if (pbar_size < -1) - pbar_size = -1; - - /* For the mini-pbar, -1 means hide, zero is invalid unless - * only one file is given */ - if (pbar_size == 0) { - if (file_list == NULL || file_list->next == NULL) - pbar_size = -1; - else - pbar_size = PBAR_SIZE_DEFAULT; - } - - /* For the label, -1 means auto-size, zero is invalid unless - * specifically requested through the use of options flag */ - if (label_size == 0 && no_labels == FALSE) - label_size = LABEL_SIZE_DEFAULT; - - /* Status update should not be zero */ - if (status_updates_per_second == 0) - status_updates_per_second = STATUS_UPDATES_PER_SEC; - } /* config != NULL */ - - /* Process the type of display we've been requested to produce */ - switch (display_type) { - case DPV_DISPLAY_STDOUT: - debug = TRUE; - use_color = FALSE; - use_dialog = FALSE; - use_libdialog = FALSE; - use_xdialog = FALSE; - break; - case DPV_DISPLAY_DIALOG: - use_color = TRUE; - use_dialog = TRUE; - use_libdialog = FALSE; - use_xdialog = FALSE; - break; - case DPV_DISPLAY_XDIALOG: - snprintf(dialog, PATH_MAX, XDIALOG); - use_color = FALSE; - use_dialog = FALSE; - use_libdialog = FALSE; - use_xdialog = TRUE; - break; - default: - use_color = TRUE; - use_dialog = FALSE; - use_libdialog = TRUE; - use_xdialog = FALSE; - break; - } /* display_type */ - - /* Enforce additional minimums that require knowing our display type */ - if (dialog_updates_per_second == 0) - dialog_updates_per_second = use_xdialog ? - XDIALOG_UPDATES_PER_SEC : DIALOG_UPDATES_PER_SEC; - - /* Allow forceful override of use_color */ - if (config != NULL && (config->options & DPV_USE_COLOR) != 0) - use_color = TRUE; - - /* Count the number of files in provided list of dpv_file_node's */ - if (use_dialog && pprompt != NULL && *pprompt != '\0') - pprompt_nls = dialog_prompt_nlstate(pprompt); - - max_cols = dialog_maxcols(); - if (label_size == -1) - shrink_label_size = TRUE; - - /* Process file arguments */ - for (curfile = file_list; curfile != NULL; curfile = curfile->next) { - dpv_nfiles++; - - /* dialog(3) only expands literal newlines */ - if (use_libdialog) strexpandnl(curfile->name); - - /* Optionally calculate label size for file */ - if (shrink_label_size) { - nls = FALSE; - name = curfile->name; - if (curfile == file_list) - nls = pprompt_nls; - last = (char *)dialog_prompt_lastline(name, nls); - if (use_dialog) { - c = *last; - *last = '\0'; - nls = dialog_prompt_nlstate(name); - *last = c; - } - len = dialog_prompt_longestline(last, nls); - if ((int)len > (label_size - 3)) { - if (label_size > 0) - label_size += 3; - label_size = len; - /* Room for ellipsis (unless NULL) */ - if (label_size > 0) - label_size += 3; - } - - if (max_cols > 0 && label_size > (max_cols - pbar_size - - 9)) - label_size = max_cols - pbar_size - 9; - } - - if (debug) - warnx("label=[%s] path=[%s] size=%lli", - curfile->name, curfile->path, curfile->length); - } /* file_list */ - - /* Optionally process the contents of DIALOGRC (~/.dialogrc) */ - if (use_dialog) { - res = parse_dialogrc(); - if (debug && res == 0) { - warnx("Successfully read `%s' config file", DIALOGRC); - warnx("use_shadow = %i (Boolean)", use_shadow); - warnx("use_colors = %i (Boolean)", use_colors); - warnx("gauge_color=[%s] (FBH)", gauge_color); - } - } else if (use_libdialog) { - init_dialog(stdin, stdout); - use_shadow = dialog_state.use_shadow; - use_colors = dialog_state.use_colors; - gauge_color[0] = 48 + dlg_color_table[GAUGE_ATTR].fg; - gauge_color[1] = 48 + dlg_color_table[GAUGE_ATTR].bg; - gauge_color[2] = dlg_color_table[GAUGE_ATTR].hilite ? - 'b' : 'B'; - gauge_color[3] = '\0'; - end_dialog(); - if (debug) { - warnx("Finished initializing dialog(3) library"); - warnx("use_shadow = %i (Boolean)", use_shadow); - warnx("use_colors = %i (Boolean)", use_colors); - warnx("gauge_color=[%s] (FBH)", gauge_color); - } - } - - /* Enable mini progress bar automatically for stdin streams if unable - * to calculate progress (missing `lines:' syntax). */ - if (dpv_nfiles <= 1 && file_list != NULL && file_list->length < 0 && - !dialog_test) - pbar_size = PBAR_SIZE_DEFAULT; - - /* If $USE_COLOR is set and non-NULL enable color; otherwise disable */ - if ((cp = getenv(ENV_USE_COLOR)) != 0) - use_color = *cp != '\0' ? 1 : 0; - - /* Print error and return `-1' if not given at least one name */ - if (dpv_nfiles == 0) { - warnx("%s: no labels provided", __func__); - return (-1); - } else if (debug) - warnx("%s: %u label%s provided", __func__, dpv_nfiles, - dpv_nfiles == 1 ? "" : "s"); - - /* If only one file and pbar size is zero, default to `-1' */ - if (dpv_nfiles <= 1 && pbar_size == 0) - pbar_size = -1; - - /* Print some debugging information */ - if (debug) { - warnx("%s: %s(%i) max rows x cols = %i x %i", - __func__, use_xdialog ? XDIALOG : DIALOG, - use_libdialog ? 3 : 1, dialog_maxrows(), - dialog_maxcols()); - } - - /* Xdialog(1) updates a lot slower than dialog(1) */ - if (dialog_test && use_xdialog) - increment = XDIALOG_INCREMENT; - - /* Always add implicit newline to pprompt (when specified) */ - if (pprompt != NULL && *pprompt != '\0') { - len = strlen(pprompt); - /* - * NOTE: pprompt = malloc(PPROMPT_MAX + 2) - * NOTE: (see getopt(2) section above for pprompt allocation) - */ - pprompt[len++] = '\\'; - pprompt[len++] = 'n'; - pprompt[len++] = '\0'; - } - - /* Xdialog(1) requires newlines (a) escaped and (b) in triplicate */ - if (use_xdialog && pprompt != NULL) { - /* Replace `\n' with `\n\\n\n' in pprompt */ - len = strlen(pprompt); - len += strcount(pprompt, "\\n") * 2; - if (len > DPV_PPROMPT_MAX) - errx(EXIT_FAILURE, "%s: Oops, pprompt buffer overflow " - "(%zu > %i)", __func__, len, DPV_PPROMPT_MAX); - if (replaceall(pprompt, "\\n", "\n\\n\n") < 0) - err(EXIT_FAILURE, "%s: replaceall()", __func__); - } - /* libdialog requires literal newlines */ - else if (use_libdialog && pprompt != NULL) - strexpandnl(pprompt); - - /* Xdialog(1) requires newlines (a) escaped and (b) in triplicate */ - if (use_xdialog && aprompt != NULL) { - /* Replace `\n' with `\n\\n\n' in aprompt */ - len = strlen(aprompt); - len += strcount(aprompt, "\\n") * 2; - if (len > DPV_APROMPT_MAX) - errx(EXIT_FAILURE, "%s: Oops, aprompt buffer overflow " - " (%zu > %i)", __func__, len, DPV_APROMPT_MAX); - if (replaceall(aprompt, "\\n", "\n\\n\n") < 0) - err(EXIT_FAILURE, "%s: replaceall()", __func__); - } - /* libdialog requires literal newlines */ - else if (use_libdialog && aprompt != NULL) - strexpandnl(aprompt); - - /* - * Warn user about an obscure dialog(1) bug (neither Xdialog(1) nor - * libdialog are affected) in the `--gauge' widget. If the first non- - * whitespace letter of "{new_prompt}" in "XXX\n{new_prompt}\nXXX\n" - * is a number, the number can sometimes be mistaken for a percentage - * to the overall progressbar. Other nasty side-effects such as the - * entire prompt not displaying or displaying improperly are caused by - * this bug too. - * - * NOTE: When we can use color, we have a work-around... prefix the - * output with `\Zn' (used to terminate ANSI and reset to normal). - */ - if (use_dialog && !use_color) { - backslash = 0; - - /* First, check pprompt (falls through if NULL) */ - fc = pprompt; - while (fc != NULL && *fc != '\0') { - if (*fc == '\n') /* leading literal newline OK */ - break; - if (!isspace(*fc) && *fc != '\\' && backslash == 0) - break; - else if (backslash > 0 && *fc != 'n') - break; - else if (*fc == '\\') { - backslash++; - if (backslash > 2) - break; /* we're safe */ - } - fc++; - } - /* First non-whitespace character that dialog(1) will see */ - if (fc != NULL && *fc >= '0' && *fc <= '9') - warnx("%s: WARNING! text argument to `-p' begins with " - "a number (not recommended)", __func__); - else if (fc > pprompt) - warnx("%s: WARNING! text argument to `-p' begins with " - "whitespace (not recommended)", __func__); - - /* - * If no pprompt or pprompt is all whitespace, check the first - * file name provided to make sure it is alright too. - */ - if ((pprompt == NULL || *fc == '\0') && file_list != NULL) { - first_file = file_list; - fc = first_file->name; - while (fc != NULL && *fc != '\0' && isspace(*fc)) - fc++; - /* First non-whitespace char that dialog(1) will see */ - if (fc != NULL && *fc >= '0' && *fc <= '9') - warnx("%s: WARNING! File name `%s' begins " - "with a number (use `-p text' for safety)", - __func__, first_file->name); - } - } - - dprompt_init(file_list); - /* Reads: label_size pbar_size pprompt aprompt dpv_nfiles */ - /* Inits: dheight and dwidth */ - - if (!debug) { - /* Internally create the initial `--gauge' prompt text */ - dprompt_recreate(file_list, (struct dpv_file_node *)NULL, 0); - - /* Spawn [X]dialog(1) `--gauge', returning pipe descriptor */ - if (use_libdialog) { - status_printf(""); - dprompt_libprint(pprompt, aprompt, 0); - } else { - dprompt_sprint(init_prompt, pprompt, aprompt); - dialog_out = dialog_spawn_gauge(init_prompt, &pid); - dprompt_dprint(dialog_out, pprompt, aprompt, 0); - } - } /* !debug */ - - /* Seed the random(3) generator */ - if (dialog_test) - srandom(0xf1eeface); - - /* Set default/custom status line format */ - if (dpv_nfiles > 1) { - snprintf(status_format_default, DPV_STATUS_FORMAT_MAX, "%s", - DPV_STATUS_MANY); - status_format_custom = config->status_many; - } else { - snprintf(status_format_default, DPV_STATUS_FORMAT_MAX, "%s", - DPV_STATUS_SOLO); - status_format_custom = config->status_solo; - } - - /* Add test mode identifier to default status line if enabled */ - if (dialog_test && (strlen(status_format_default) + 12) < - DPV_STATUS_FORMAT_MAX) - strcat(status_format_default, " [TEST MODE]"); - - /* Verify custom status format */ - status_fmt = fmtcheck(status_format_custom, status_format_default); - if (status_format_custom != NULL && - status_fmt == status_format_default) { - warnx("WARNING! Invalid status_format configuration `%s'", - status_format_custom); - warnx("Default status_format `%s'", status_format_default); - } - - /* Record when we started (used to prevent updating too quickly) */ - (void)gettimeofday(&start, (struct timezone *)NULL); - - /* Calculate number of microseconds in-between sub-second updates */ - if (status_updates_per_second != 0) - status_update_usec = 1000000 / status_updates_per_second; - if (dialog_updates_per_second != 0) - dialog_update_usec = 1000000 / dialog_updates_per_second; - - /* - * Process the file list [serially] (one for each argument passed) - */ - files_left = dpv_nfiles; - list_head = file_list; - for (curfile = file_list; curfile != NULL; curfile = curfile->next) { - keep_going = TRUE; - output_out = -1; - pct = 0; - nthfile++; - files_left--; - - if (dpv_interrupt) - break; - if (dialog_test) - pct = 0 - increment; - - /* Attempt to spawn output program for this file */ - if (!dialog_test && output != NULL) { - mask = umask(0022); - (void)umask(mask); - - switch (output_type) { - case DPV_OUTPUT_SHELL: - output_out = shell_spawn_pipecmd(output, - curfile->name, &output_pid); - break; - case DPV_OUTPUT_FILE: - path_fmt = fmtcheck(output, "%s"); - if (path_fmt == output) - len = snprintf(pathbuf, - PATH_MAX, output, curfile->name); - else - len = snprintf(pathbuf, - PATH_MAX, "%s", output); - if (len >= PATH_MAX) { - warnx("%s:%d:%s: pathbuf[%u] too small" - "to hold output argument", - __FILE__, __LINE__, __func__, - PATH_MAX); - return (-1); - } - if ((output_out = open(pathbuf, - O_CREAT|O_WRONLY, DEFFILEMODE & ~mask)) - < 0) { - warn("%s", pathbuf); - return (-1); - } - break; - default: - break; - } - } - - while (!dpv_interrupt && keep_going) { - if (dialog_test) { - usleep(50000); - pct += increment; - dpv_overall_read += - (int)(random() / 512 / dpv_nfiles); - /* 512 limits fake readout to Megabytes */ - } else if (action != NULL) - pct = action(curfile, output_out); - - if (no_overrun || dialog_test) - keep_going = (pct < 100); - else { - status = curfile->status; - keep_going = (status == DPV_STATUS_RUNNING); - } - - /* Get current time and calculate seconds elapsed */ - gettimeofday(&now, (struct timezone *)NULL); - now.tv_sec = now.tv_sec - start.tv_sec; - now.tv_usec = now.tv_usec - start.tv_usec; - if (now.tv_usec < 0) - now.tv_sec--, now.tv_usec += 1000000; - seconds = now.tv_sec + (now.tv_usec / 1000000.0); - - /* Update dialog (be it dialog(3), dialog(1), etc.) */ - if ((dialog_updates_per_second != 0 && - ( - seconds != dialog_old_seconds || - now.tv_usec - dialog_last_update >= - dialog_update_usec || - nthfile != dialog_old_nthfile - )) || pct == 100 - ) { - /* Calculate overall progress (rounding up) */ - overall = (100 * nthfile - 100 + pct) / - dpv_nfiles; - if (((100 * nthfile - 100 + pct) * 10 / - dpv_nfiles % 100) > 50) - overall++; - - dprompt_recreate(list_head, curfile, pct); - - if (use_libdialog && !debug) { - /* Update dialog(3) widget */ - dprompt_libprint(pprompt, aprompt, - overall); - } else { - /* stdout, dialog(1), or Xdialog(1) */ - dprompt_dprint(dialog_out, pprompt, - aprompt, overall); - fsync(dialog_out); - } - dialog_old_seconds = seconds; - dialog_old_nthfile = nthfile; - dialog_last_update = now.tv_usec; - } - - /* Update the status line */ - if ((use_libdialog && !debug) && - status_updates_per_second != 0 && - ( - keep_going != TRUE || - seconds != status_old_seconds || - now.tv_usec - status_last_update >= - status_update_usec || - nthfile != status_old_nthfile - ) - ) { - status_printf(status_fmt, dpv_overall_read, - (dpv_overall_read / (seconds == 0 ? 1 : - seconds) * 1.0), - 1, /* XXX until we add parallelism XXX */ - files_left); - status_old_seconds = seconds; - status_old_nthfile = nthfile; - status_last_update = now.tv_usec; - } - } - - if (!dialog_test && output_out >= 0) { - close(output_out); - waitpid(output_pid, (int *)NULL, 0); - } - - if (dpv_abort) - break; - - /* Advance head of list when we hit the max display lines */ - if (display_limit > 0 && nthfile % display_limit == 0) - list_head = curfile->next; - } - - if (!debug) { - if (use_libdialog) - end_dialog(); - else { - close(dialog_out); - waitpid(pid, (int *)NULL, 0); - } - if (!dpv_interrupt) - printf("\n"); - } else - warnx("%s: %lli lines read", __func__, dpv_overall_read); - - if (dpv_interrupt || dpv_abort) - return (-1); - else - return (0); -} - -/* - * Free allocated items initialized by dpv() - */ -void -dpv_free(void) -{ - dialogrc_free(); - dprompt_free(); - dialog_maxsize_free(); - if (aprompt != NULL) { - free(aprompt); - aprompt = NULL; - } - if (pprompt != NULL) { - free(pprompt); - pprompt = NULL; - } - status_free(); -} diff --git a/lib/libdpv/dpv.h b/lib/libdpv/dpv.h deleted file mode 100644 index dbcd59bd6..000000000 --- a/lib/libdpv/dpv.h +++ /dev/null @@ -1,161 +0,0 @@ -/*- - * Copyright (c) 2013-2014 Devin Teske - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * $FreeBSD$ - */ - -#ifndef _DPV_H_ -#define _DPV_H_ - -#include - -#ifndef TRUE -#define TRUE 1 -#endif -#ifndef FALSE -#define FALSE 0 -#endif - -/* Data to process */ -extern long long dpv_overall_read; - -/* Interrupt flag */ -extern int dpv_interrupt; /* Set to TRUE in interrupt handler */ -extern int dpv_abort; /* Set to true in callback to abort */ - -/* - * Display types for use with display_type member of dpv_config structure - */ -enum dpv_display { - DPV_DISPLAY_LIBDIALOG = 0, /* Display using dialog(3) (default) */ - DPV_DISPLAY_STDOUT, /* Display on stdout */ - DPV_DISPLAY_DIALOG, /* Display using spawned dialog(1) */ - DPV_DISPLAY_XDIALOG, /* Display using spawned Xdialog(1) */ -}; - -/* - * Output types for use with output_type member of dpv_config structure - */ -enum dpv_output { - DPV_OUTPUT_NONE = 0, /* No output (default) */ - DPV_OUTPUT_FILE, /* Read `output' member as file path */ - DPV_OUTPUT_SHELL, /* Read `output' member as shell cmd */ -}; - -/* - * Activity types for use with status member of dpv_file_node structure. - * If you set a status other than DPV_STATUS_RUNNING on the current file in the - * action callback of dpv_config structure, you'll end callbacks for that - * dpv_file_node. - */ -enum dpv_status { - DPV_STATUS_RUNNING = 0, /* Running (default) */ - DPV_STATUS_DONE, /* Completed */ - DPV_STATUS_FAILED, /* Oops, something went wrong */ -}; - -/* - * Anatomy of file option; pass an array of these as dpv() file_list argument - * terminated with a NULL pointer. - */ -struct dpv_file_node { - enum dpv_status status; /* status of read operation */ - char *msg; /* display instead of "Done/Fail" */ - char *name; /* name of file to read */ - char *path; /* path to file */ - long long length; /* expected size */ - long long read; /* number units read (e.g., bytes) */ - struct dpv_file_node *next; /* pointer to next (end with NULL) */ -}; - -/* - * Anatomy of config option to pass as dpv() config argument - */ -struct dpv_config { - enum dpv_display display_type; /* Display (default TYPE_LIBDIALOG) */ - enum dpv_output output_type; /* Output (default TYPE_NONE) */ - int debug; /* Enable debugging output on stderr */ - int display_limit; /* Files per `page'. Default -1 */ - int label_size; /* Label size. Default 28 */ - int pbar_size; /* Mini-progress size. See dpv(3) */ - int dialog_updates_per_second; /* Progress updates/s. Default 16 */ - int status_updates_per_second; /* dialog(3) status updates/second. - * Default 2 */ - uint16_t options; /* Special options. Default 0 */ - char *title; /* widget title */ - char *backtitle; /* Widget backtitle */ - char *aprompt; /* Prompt append. Default NULL */ - char *pprompt; /* Prompt prefix. Default NULL */ - char *msg_done; /* Progress text. Default `Done' */ - char *msg_fail; /* Progress text. Default `Fail' */ - char *msg_pending; /* Progress text. Default `Pending' */ - char *output; /* Output format string; see dpv(3) */ - const char *status_solo; /* dialog(3) solo-status format. - * Default DPV_STATUS_SOLO */ - const char *status_many; /* dialog(3) many-status format. - * Default DPV_STATUS_MANY */ - - /* - * Function pointer; action to perform data transfer - */ - int (*action)(struct dpv_file_node *file, int out); -}; - -/* - * Macros for dpv() options bitmask argument - */ -#define DPV_TEST_MODE 0x0001 /* Test mode (fake reading data) */ -#define DPV_WIDE_MODE 0x0002 /* prefix/append bump dialog width */ -#define DPV_NO_LABELS 0x0004 /* Hide file_node.name labels */ -#define DPV_USE_COLOR 0x0008 /* Override to force color output */ -#define DPV_NO_OVERRUN 0x0010 /* Stop transfers when they hit 100% */ - -/* - * Limits (modify with extreme care) - */ -#define DPV_APROMPT_MAX 4096 /* Buffer size for `-a text' */ -#define DPV_DISPLAY_LIMIT 10 /* Max file progress lines */ -#define DPV_PPROMPT_MAX 4096 /* Buffer size for `-p text' */ -#define DPV_STATUS_FORMAT_MAX 80 /* Buffer size for `-u format' */ - -/* - * Extra display information - */ -#define DPV_STATUS_SOLO "%'10lli bytes read @ %'9.1f bytes/sec." -#define DPV_STATUS_MANY (DPV_STATUS_SOLO " [%i/%i busy/wait]") - -/* - * Strings - */ -#define DPV_DONE_DEFAULT "Done" -#define DPV_FAIL_DEFAULT "Fail" -#define DPV_PENDING_DEFAULT "Pending" - -__BEGIN_DECLS -void dpv_free(void); -int dpv(struct dpv_config *_config, struct dpv_file_node *_file_list); -__END_DECLS - -#endif /* !_DPV_H_ */ diff --git a/lib/libdpv/dpv_private.h b/lib/libdpv/dpv_private.h deleted file mode 100644 index 5164eb321..000000000 --- a/lib/libdpv/dpv_private.h +++ /dev/null @@ -1,66 +0,0 @@ -/*- - * Copyright (c) 2013-2014 Devin Teske - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * $FreeBSD$ - */ - -#ifndef _DPV_PRIVATE_H_ -#define _DPV_PRIVATE_H_ - -#include - -/* Debugging */ -extern uint8_t debug; - -/* Data to process */ -extern unsigned int dpv_nfiles; - -/* Extra display information */ -extern uint8_t no_labels; -extern uint8_t wide; -extern char *msg_done, *msg_fail, *msg_pending; -extern char *pprompt, *aprompt; -extern const char status_format[]; - -/* Defaults */ -#define DIALOG_UPDATES_PER_SEC 16 -#define XDIALOG_UPDATES_PER_SEC 4 -#define DISPLAY_LIMIT_DEFAULT 0 /* Auto-calculate */ -#define LABEL_SIZE_DEFAULT 28 -#define PBAR_SIZE_DEFAULT 17 -#define STATUS_UPDATES_PER_SEC 2 - -/* states for dprompt_add_files() of dprompt.c */ -enum dprompt_state { - DPROMPT_NONE = 0, /* Default */ - DPROMPT_PENDING, /* Pending */ - DPROMPT_PBAR, /* Progress bar */ - DPROMPT_END_STATE, /* Done/Fail */ - DPROMPT_DETAILS, /* dpv_file_node->read */ - DPROMPT_CUSTOM_MSG, /* dpv_file_node->msg */ - DPROMPT_MINIMAL, /* whitespace */ -}; - -#endif /* !_DPV_PRIVATE_H_ */ diff --git a/lib/libdpv/status.c b/lib/libdpv/status.c deleted file mode 100644 index 4bf477356..000000000 --- a/lib/libdpv/status.c +++ /dev/null @@ -1,111 +0,0 @@ -/*- - * Copyright (c) 2013-2014 Devin Teske - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - */ - -#include -__FBSDID("$FreeBSD$"); - -#include -#include -#include -#include -#include - -#include "dialog_util.h" -#include "status.h" - -/* static globals */ -static char *status_buf = NULL; -static int status_bufsize = -1; -static int status_row; -static int status_width; - -/* - * Print a `one-liner' status message at the bottom of the screen. Messages are - * trimmed to fit within the console length (ANSI coloring not accounted for). - */ -void -status_printf(const char *fmt, ...) -{ - int n, attrs; - chtype color = dlg_color_pair(dlg_color_table[BUTTON_ACTIVE_ATTR].fg, - dlg_color_table[SCREEN_ATTR].bg) | A_BOLD; - va_list args; - - status_row = tty_maxrows() - 1; - status_width = tty_maxcols(); - - /* NULL is a special convention meaning "erase the old stuff" */ - if (fmt == NULL) { - move(status_row, 0); - clrtoeol(); - return; - } - - /* Resize buffer if terminal width is greater */ - if ((status_width + 1) > status_bufsize) { - status_buf = realloc(status_buf, status_width + 1); - if (status_buf == NULL) { - status_bufsize = -1; - return; - } - status_bufsize = status_width + 1; - } - - /* Print the message within a space-filled buffer */ - memset(status_buf, ' ', status_width); - va_start(args, fmt); - n = vsnprintf(status_buf, status_width + 1, fmt, args); - va_end(args); - - /* If vsnprintf(3) produced less bytes than the maximum, change the - * implicitly-added NUL-terminator into a space and terminate at max */ - if (n < status_width) { - status_buf[n] = ' '; - status_buf[status_width] = '\0'; - } - - /* Print text in screen bg, button active fg, and bold */ - attrs = getattrs(stdscr); - attrset(color); - mvaddstr(status_row, 0, status_buf); - attrset(attrs); - - /* Seat the cursor over the last character at absolute lower-right */ - move(status_row, status_width - 1); - refresh(); -} - -/* - * Free allocated items initialized by status_printf() - */ -void -status_free(void) -{ - if (status_buf != NULL) { - free(status_buf); - status_buf = NULL; - } -} diff --git a/lib/libdpv/status.h b/lib/libdpv/status.h deleted file mode 100644 index 002f7f182..000000000 --- a/lib/libdpv/status.h +++ /dev/null @@ -1,43 +0,0 @@ -/*- - * Copyright (c) 2013-2014 Devin Teske - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * $FreeBSD$ - */ - -#ifndef _STATUS_H_ -#define _STATUS_H_ - -#include - -/* dialog(3) dlg_color_table[] attributes */ -#define SCREEN_ATTR 0 /* entry used for status line bg */ -#define BUTTON_ACTIVE_ATTR 5 /* entry used for status line fg */ - -__BEGIN_DECLS -void status_free(void); -void status_printf(const char *_format, ...); -__END_DECLS - -#endif /* !_STATUS_H_ */ diff --git a/lib/libdpv/util.c b/lib/libdpv/util.c deleted file mode 100644 index 25fc1cb03..000000000 --- a/lib/libdpv/util.c +++ /dev/null @@ -1,107 +0,0 @@ -/*- - * Copyright (c) 2013-2014 Devin Teske - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - */ - -#include -__FBSDID("$FreeBSD$"); - -#include -#include -#include -#include -#include -#include - -#include "util.h" - -extern char **environ; -static char cmdbuf[CMDBUFMAX] = ""; -static char shellcmd[PATH_MAX] = PATH_SHELL; -static char *shellcmd_argv[6] = { - shellcmd, - __DECONST(char *, "-c"), - cmdbuf, - __DECONST(char *, "--"), - shellcmd, - NULL, -}; - -/* - * Spawn a sh(1) command. Writes the resulting process ID to the pid_t pointed - * at by `pid'. Returns a file descriptor (int) suitable for writing data to - * the spawned command (data written to file descriptor is seen as standard-in - * by the spawned sh(1) command). Returns `-1' if unable to spawn command. - * - * If cmd contains a single "%s" sequence, replace it with label if non-NULL. - */ -int -shell_spawn_pipecmd(const char *cmd, const char *label, pid_t *pid) -{ - int error; - int len; - posix_spawn_file_actions_t action; -#if SHELL_SPAWN_DEBUG - unsigned int i; -#endif - int stdin_pipe[2] = { -1, -1 }; - - /* Populate argument array */ - if (label != NULL && fmtcheck(cmd, "%s") == cmd) - len = snprintf(cmdbuf, CMDBUFMAX, cmd, label); - else - len = snprintf(cmdbuf, CMDBUFMAX, "%s", cmd); - if (len >= CMDBUFMAX) { - warnx("%s:%d:%s: cmdbuf[%u] too small to hold cmd argument", - __FILE__, __LINE__, __func__, CMDBUFMAX); - return (-1); - } - - /* Open a pipe to communicate with [X]dialog(1) */ - if (pipe(stdin_pipe) < 0) - err(EXIT_FAILURE, "%s: pipe(2)", __func__); - - /* Fork sh(1) process */ -#if SHELL_SPAWN_DEBUG - fprintf(stderr, "%s: spawning `", __func__); - for (i = 0; shellcmd_argv[i] != NULL; i++) { - if (i == 0) - fprintf(stderr, "%s", shellcmd_argv[i]); - else if (i == 2) - fprintf(stderr, " '%s'", shellcmd_argv[i]); - else - fprintf(stderr, " %s", shellcmd_argv[i]); - } - fprintf(stderr, "'\n"); -#endif - posix_spawn_file_actions_init(&action); - posix_spawn_file_actions_adddup2(&action, stdin_pipe[0], STDIN_FILENO); - posix_spawn_file_actions_addclose(&action, stdin_pipe[1]); - error = posix_spawnp(pid, shellcmd, &action, - (const posix_spawnattr_t *)NULL, shellcmd_argv, environ); - if (error != 0) - err(EXIT_FAILURE, "%s: posix_spawnp(3)", __func__); - - return stdin_pipe[1]; -} diff --git a/lib/libdpv/util.h b/lib/libdpv/util.h deleted file mode 100644 index 7bb3b1890..000000000 --- a/lib/libdpv/util.h +++ /dev/null @@ -1,50 +0,0 @@ -/*- - * Copyright (c) 2013-2014 Devin Teske - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * $FreeBSD$ - */ - -#ifndef _UTIL_H_ -#define _UTIL_H_ - -#include - -#include - -#define SHELL_SPAWN_DEBUG 0 /* Debug spawning of sh(1) commands */ - -#ifdef _PATH_BSHELL -#define PATH_SHELL _PATH_BSHELL -#else -#define PATH_SHELL "/bin/sh" -#endif - -#define CMDBUFMAX 4096 - -__BEGIN_DECLS -int shell_spawn_pipecmd(const char *_cmd, const char *_label, pid_t *_pid); -__END_DECLS - -#endif /* !_UTIL_H_ */ diff --git a/lib/libfigpar/Makefile b/lib/libfigpar/Makefile deleted file mode 100644 index 6f0196606..000000000 --- a/lib/libfigpar/Makefile +++ /dev/null @@ -1,21 +0,0 @@ -# $FreeBSD$ - -LIB= figpar -SHLIB_MAJOR= 0 -INCS= figpar.h string_m.h -MAN= figpar.3 -MLINKS= figpar.3 get_config_option.3 \ - figpar.3 parse_config.3 \ - figpar.3 replaceall.3 \ - figpar.3 strcount.3 \ - figpar.3 strexpand.3 \ - figpar.3 strexpandnl.3 \ - figpar.3 strtolower.3 - -CFLAGS+= -I${.CURDIR} - -SRCS= figpar.c string_m.c - -WARNS?= 6 - -.include diff --git a/lib/libfigpar/figpar.3 b/lib/libfigpar/figpar.3 deleted file mode 100644 index 549808e8e..000000000 --- a/lib/libfigpar/figpar.3 +++ /dev/null @@ -1,251 +0,0 @@ -.\" Copyright (c) 2013-2014 Devin Teske -.\" All rights reserved. -.\" -.\" Redistribution and use in source and binary forms, with or without -.\" modification, are permitted provided that the following conditions -.\" are met: -.\" 1. Redistributions of source code must retain the above copyright -.\" notice, this list of conditions and the following disclaimer. -.\" 2. Redistributions in binary form must reproduce the above copyright -.\" notice, this list of conditions and the following disclaimer in the -.\" documentation and/or other materials provided with the distribution. -.\" -.\" THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND -.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE -.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE -.\" ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE -.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL -.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS -.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) -.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT -.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY -.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF -.\" SUCH DAMAGE. -.\" -.\" $FreeBSD$ -.\" -.Dd Oct 24, 2014 -.Dt FIGPAR 3 -.Os -.Sh NAME -.Nm figpar , -.Nm parse_config , -.Nm get_config_option -.Nd configuration file parsing library -.Sh LIBRARY -.Lb libfigpar -.Sh SYNOPSIS -.In figpar.h -.Ft int -.Fo parse_config -.Fa "struct fp_config options[], const char *path" -.Fa "int \*[lp]*unknown\*[rp]\*[lp]struct fp_config *option, uint32_t line" -.Fa "char *directive, char *value\*[rp], uint8_t processing_options" -.Fc -.Ft "struct fp_config *" -.Fo get_config_option -.Fa "struct fp_config options[], const char *directive" -.Fc -.In string_m.h -.Ft int -.Fo replaceall -.Fa "char *source, const char *find, const char *replace" -.Fc -.Ft unsigned int -.Fo strcount -.Fa "const char *source, const char *find" -.Fc -.Ft void -.Fo strexpand -.Fa "char *source" -.Fc -.Ft void -.Fo strexpandnl -.Fa "char *source" -.Fc -.Ft void -.Fo strtolower -.Fa "char *source" -.Fc -.Sh DESCRIPTION -The -.Nm -library provides a light-weight, portable framework for parsing configuration -files. -The library uses -.Xr open 2 , -.Xr read 2 , -and -.Xr lseek 2 -within the file pointed to by -.Fa path -to find directives and values which are then made available to the application. -.Pp -Due to the fact that configuration files may have basic syntax differences, -the library does not attempt to impose any structure on the data but instead -provides raw data to a set of callback functions. -These callback functions can in-turn initiate abort through their return value, -allowing custom syntax validation during parsing. -.Pp -Configuration directives, types, and callback functions are provided through -data structures defined in -.In figpar.h : -.Bd -literal -offset indent -struct fp_config { - enum fp_cfgtype type; /* value type */ - const char *directive; /* keyword */ - union fp_cfgvalue value; /* value */ - - /* Pointer to function used when directive is found */ - int (*action)(struct fp_config *option, uint32_t line, - char *directive, char *value); -}; - -enum fp_cfgtype { - FP_TYPE_NONE = 0x0000, /* for directives with no value */ - FP_TYPE_BOOL = 0x0001, /* boolean */ - FP_TYPE_INT = 0x0002, /* signed 32 bit integer */ - FP_TYPE_UINT = 0x0004, /* unsigned 32 bit integer */ - FP_TYPE_STR = 0x0008, /* string pointer */ - FP_TYPE_STRARRAY = 0x0010, /* string array pointer */ - FP_TYPE_DATA1 = 0x0020, /* void data type-1 (whatever) */ - FP_TYPE_DATA2 = 0x0040, /* void data type-2 (whatever) */ - FP_TYPE_DATA3 = 0x0080, /* void data type-3 (whatever) */ - FP_TYPE_RESERVED1 = 0x0100, /* reserved data type-1 (future) */ - FP_TYPE_RESERVED2 = 0x0200, /* reserved data type-2 (future) */ - FP_TYPE_RESERVED3 = 0x0400, /* reserved data type-3 (future) */ -}; - -union fp_cfgvalue { - void *data; /* Pointer to NUL-terminated string */ - char *str; /* Pointer to NUL-terminated string */ - char **strarray; /* Pointer to an array of strings */ - int32_t num; /* Signed 32-bit integer value */ - uint32_t u_num; /* Unsigned 32-bit integer value */ - uint32_t boolean:1; /* Boolean integer value (0 or 1) */ -}; -.Ed -.Pp -The -.Fa processing_options -argument to -.Fn parse_config -is a mask of bit fields which indicate various -processing options. -The possible flags are as follows: -.Bl -tag -width FP_BREAK_ON_SEMICOLON -.It Dv FP_BREAK_ON_EQUALS -An equals sign -.Pq Ql Li = -is normally considered part of the directive. -This flag enables terminating the directive at the equals sign. -Also makes equals sign optional and transient. -.It Dv FP_BREAK_ON_SEMICOLON -A semicolon -.Pq Ql Li \; -is normally considered part of the value. -This flag enables terminating the value at the semicolon. -Also allows multiple statements on a single line separated by semicolon. -.It Dv FP_CASE_SENSITIVE -Normally directives are matched case insensitively using -.Xr fnmatch 3 . -This flag enables directive matching to be case sensitive. -.It Dv FP_REQUIRE_EQUALS -If a directive is not followed by an equals, processing is aborted. -.It Dv FP_STRICT_EQUALS -Equals must be part of the directive to be considered a delimiter between -directive and value. -.El -.Pp -The -.Fa options -struct array pointer can be NULL and every directive will invoke the -.Fn unknown -function argument. -.Pp -The directive for each fp_config item in the -.Fn parse_config -options argument is matched against each parsed directive using -.Xr fnmatch 3 -until a match is found. -If a match is found, the -.Fn action -function for that fp_config directive is invoked with the line number, -directive, and value. -Otherwise if no match, the -.Fn unknown -function is invoked -.Pq with the same arguments . -.Pp -If either -.Fa action -or -.Fa unknown -return non-zero, -.Fn parse_config -aborts reading the file and returns the error value to its caller. -.Pp -.Fn get_config_option -traverses the options-array and returns the option that matches via -.Xr strcmp 3 , -or if no match a pointer to a static dummy struct is returned -.Pq whose values are all zero or NULL . -.Pp -The use of -.Fa "struct fp_config" -is entirely optional as-is the use of -.Fa "enum fp_cfgtype" -or -.Fa "union fp_cfgvalue" . -For example, you could choose to pass a NULL pointer to -.Fn parse_config -for the first argument and then provide a simple -.Fa unknown -function based on -.Xr queue 3 -that populates a singly-linked list of your own struct containing the -.Fa directive -and -.Fa value . -.Pp -In addition, the following miscellaneous string manipulation routines are -provided by -.In string_m.h : -.Bl -tag -width strexpandnl() -.It Fn replaceall -Replace all occurrences of -.Fa find -in -.Fa source -with -.Fa replace . -.It Fn strcount -Count the number of occurrences of one string that appear in the -.Fa source -string. -Return value is the total count. -An example use would be if you need to know how large a block of memory needs -to be for a -.Fn replaceall -series. -.It Fn strexpand -Expand escape sequences in a buffer pointed to by -.Fa source . -.It Fn strexpandnl -Expand only the escaped newlines in a buffer pointed to by -.Fa source . -.It Fn strtolower -Convert a string to lower case. -.El -.Sh SEE ALSO -.Xr queue 3 -.Sh HISTORY -The -.Nm -library first appeared in -.Fx 11.0 . -.Sh AUTHORS -.An Devin Teske Aq dteske@FreeBSD.org -.Sh BUGS -This is the first implementation of the library, -and the interface may be subject to refinement. diff --git a/lib/libfigpar/figpar.c b/lib/libfigpar/figpar.c deleted file mode 100644 index a97fc85e9..000000000 --- a/lib/libfigpar/figpar.c +++ /dev/null @@ -1,469 +0,0 @@ -/*- - * Copyright (c) 2002-2014 Devin Teske - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - */ - -#include -__FBSDID("$FreeBSD$"); - -#include - -#include -#include -#include -#include -#include -#include -#include - -#include "figpar.h" -#include "string_m.h" - -struct fp_config fp_dummy_config = {0, NULL, {0}, NULL}; - -/* - * Search for config option (struct fp_config) in the array of config options, - * returning the struct whose directive matches the given parameter. If no - * match is found, a pointer to the static dummy array (above) is returned. - * - * This is to eliminate dependency on the index position of an item in the - * array, since the index position is more apt to be changed as code grows. - */ -struct fp_config * -get_config_option(struct fp_config options[], const char *directive) -{ - uint32_t n; - - /* Check arguments */ - if (options == NULL || directive == NULL) - return (&fp_dummy_config); - - /* Loop through the array, return the index of the first match */ - for (n = 0; options[n].directive != NULL; n++) - if (strcmp(options[n].directive, directive) == 0) - return (&(options[n])); - - /* Re-initialize the dummy variable in case it was written to */ - fp_dummy_config.directive = NULL; - fp_dummy_config.type = 0; - fp_dummy_config.action = NULL; - fp_dummy_config.value.u_num = 0; - - return (&fp_dummy_config); -} - -/* - * Parse the configuration file at `path' and execute the `action' call-back - * functions for any directives defined by the array of config options (first - * argument). - * - * For unknown directives that are encountered, you can optionally pass a - * call-back function for the third argument to be called for unknowns. - * - * Returns zero on success; otherwise returns -1 and errno should be consulted. -*/ -int -parse_config(struct fp_config options[], const char *path, - int (*unknown)(struct fp_config *option, uint32_t line, char *directive, - char *value), uint16_t processing_options) -{ - uint8_t bequals; - uint8_t bsemicolon; - uint8_t case_sensitive; - uint8_t comment = 0; - uint8_t end; - uint8_t found; - uint8_t have_equals = 0; - uint8_t quote; - uint8_t require_equals; - uint8_t strict_equals; - char p[2]; - char *directive; - char *t; - char *value; - int error; - int fd; - ssize_t r = 1; - uint32_t dsize; - uint32_t line = 1; - uint32_t n; - uint32_t vsize; - uint32_t x; - off_t charpos; - off_t curpos; - char rpath[PATH_MAX]; - - /* Sanity check: if no options and no unknown function, return */ - if (options == NULL && unknown == NULL) - return (-1); - - /* Processing options */ - bequals = (processing_options & FP_BREAK_ON_EQUALS) == 0 ? 0 : 1; - bsemicolon = (processing_options & FP_BREAK_ON_SEMICOLON) == 0 ? 0 : 1; - case_sensitive = (processing_options & FP_CASE_SENSITIVE) == 0 ? 0 : 1; - require_equals = (processing_options & FP_REQUIRE_EQUALS) == 0 ? 0 : 1; - strict_equals = (processing_options & FP_STRICT_EQUALS) == 0 ? 0 : 1; - - /* Initialize strings */ - directive = value = 0; - vsize = dsize = 0; - - /* Resolve the file path */ - if (realpath(path, rpath) == 0) - return (-1); - - /* Open the file */ - if ((fd = open(rpath, O_RDONLY)) < 0) - return (-1); - - /* Read the file until EOF */ - while (r != 0) { - r = read(fd, p, 1); - - /* skip to the beginning of a directive */ - while (r != 0 && (isspace(*p) || *p == '#' || comment || - (bsemicolon && *p == ';'))) { - if (*p == '#') - comment = 1; - else if (*p == '\n') { - comment = 0; - line++; - } - r = read(fd, p, 1); - } - /* Test for EOF; if EOF then no directive was found */ - if (r == 0) { - close(fd); - return (0); - } - - /* Get the current offset */ - curpos = lseek(fd, 0, SEEK_CUR) - 1; - if (curpos == -1) { - close(fd); - return (-1); - } - - /* Find the length of the directive */ - for (n = 0; r != 0; n++) { - if (isspace(*p)) - break; - if (bequals && *p == '=') { - have_equals = 1; - break; - } - if (bsemicolon && *p == ';') - break; - r = read(fd, p, 1); - } - - /* Test for EOF, if EOF then no directive was found */ - if (n == 0 && r == 0) { - close(fd); - return (0); - } - - /* Go back to the beginning of the directive */ - error = (int)lseek(fd, curpos, SEEK_SET); - if (error == (curpos - 1)) { - close(fd); - return (-1); - } - - /* Allocate and read the directive into memory */ - if (n > dsize) { - if ((directive = realloc(directive, n + 1)) == NULL) { - close(fd); - return (-1); - } - dsize = n; - } - r = read(fd, directive, n); - - /* Advance beyond the equals sign if appropriate/desired */ - if (bequals && *p == '=') { - if (lseek(fd, 1, SEEK_CUR) != -1) - r = read(fd, p, 1); - if (strict_equals && isspace(*p)) - *p = '\n'; - } - - /* Terminate the string */ - directive[n] = '\0'; - - /* Convert directive to lower case before comparison */ - if (!case_sensitive) - strtolower(directive); - - /* Move to what may be the start of the value */ - if (!(bsemicolon && *p == ';') && - !(strict_equals && *p == '=')) { - while (r != 0 && isspace(*p) && *p != '\n') - r = read(fd, p, 1); - } - - /* An equals sign may have stopped us, should we eat it? */ - if (r != 0 && bequals && *p == '=' && !strict_equals) { - have_equals = 1; - r = read(fd, p, 1); - while (r != 0 && isspace(*p) && *p != '\n') - r = read(fd, p, 1); - } - - /* If no value, allocate a dummy value and jump to action */ - if (r == 0 || *p == '\n' || *p == '#' || - (bsemicolon && *p == ';')) { - /* Initialize the value if not already done */ - if (value == NULL && (value = malloc(1)) == NULL) { - close(fd); - return (-1); - } - value[0] = '\0'; - goto call_function; - } - - /* Get the current offset */ - curpos = lseek(fd, 0, SEEK_CUR) - 1; - if (curpos == -1) { - close(fd); - return (-1); - } - - /* Find the end of the value */ - quote = 0; - end = 0; - while (r != 0 && end == 0) { - /* Advance to the next character if we know we can */ - if (*p != '\"' && *p != '#' && *p != '\n' && - (!bsemicolon || *p != ';')) { - r = read(fd, p, 1); - continue; - } - - /* - * If we get this far, we've hit an end-key - */ - - /* Get the current offset */ - charpos = lseek(fd, 0, SEEK_CUR) - 1; - if (charpos == -1) { - close(fd); - return (-1); - } - - /* - * Go back so we can read the character before the key - * to check if the character is escaped (which means we - * should continue). - */ - error = (int)lseek(fd, -2, SEEK_CUR); - if (error == -3) { - close(fd); - return (-1); - } - r = read(fd, p, 1); - - /* - * Count how many backslashes there are (an odd number - * means the key is escaped, even means otherwise). - */ - for (n = 1; *p == '\\'; n++) { - /* Move back another offset to read */ - error = (int)lseek(fd, -2, SEEK_CUR); - if (error == -3) { - close(fd); - return (-1); - } - r = read(fd, p, 1); - } - - /* Move offset back to the key and read it */ - error = (int)lseek(fd, charpos, SEEK_SET); - if (error == (charpos - 1)) { - close(fd); - return (-1); - } - r = read(fd, p, 1); - - /* - * If an even number of backslashes was counted meaning - * key is not escaped, we should evaluate what to do. - */ - if ((n & 1) == 1) { - switch (*p) { - case '\"': - /* - * Flag current sequence of characters - * to follow as being quoted (hashes - * are not considered comments). - */ - quote = !quote; - break; - case '#': - /* - * If we aren't in a quoted series, we - * just hit an inline comment and have - * found the end of the value. - */ - if (!quote) - end = 1; - break; - case '\n': - /* - * Newline characters must always be - * escaped, whether inside a quoted - * series or not, otherwise they - * terminate the value. - */ - end = 1; - case ';': - if (!quote && bsemicolon) - end = 1; - break; - } - } else if (*p == '\n') - /* Escaped newline character. increment */ - line++; - - /* Advance to the next character */ - r = read(fd, p, 1); - } - - /* Get the current offset */ - charpos = lseek(fd, 0, SEEK_CUR) - 1; - if (charpos == -1) { - close(fd); - return (-1); - } - - /* Get the length of the value */ - n = (uint32_t)(charpos - curpos); - if (r != 0) /* more to read, but don't read ending key */ - n--; - - /* Move offset back to the beginning of the value */ - error = (int)lseek(fd, curpos, SEEK_SET); - if (error == (curpos - 1)) { - close(fd); - return (-1); - } - - /* Allocate and read the value into memory */ - if (n > vsize) { - if ((value = realloc(value, n + 1)) == NULL) { - close(fd); - return (-1); - } - vsize = n; - } - r = read(fd, value, n); - - /* Terminate the string */ - value[n] = '\0'; - - /* Cut trailing whitespace off by termination */ - t = value + n; - while (isspace(*--t)) - *t = '\0'; - - /* Escape the escaped quotes (replaceall is in string_m.c) */ - x = strcount(value, "\\\""); /* in string_m.c */ - if (x != 0 && (n + x) > vsize) { - if ((value = realloc(value, n + x + 1)) == NULL) { - close(fd); - return (-1); - } - vsize = n + x; - } - if (replaceall(value, "\\\"", "\\\\\"") < 0) { - /* Replace operation failed for some unknown reason */ - close(fd); - return (-1); - } - - /* Remove all new line characters */ - if (replaceall(value, "\\\n", "") < 0) { - /* Replace operation failed for some unknown reason */ - close(fd); - return (-1); - } - - /* Resolve escape sequences */ - strexpand(value); /* in string_m.c */ - -call_function: - /* Abort if we're seeking only assignments */ - if (require_equals && !have_equals) - return (-1); - - found = have_equals = 0; /* reset */ - - /* If there are no options defined, call unknown and loop */ - if (options == NULL && unknown != NULL) { - error = unknown(NULL, line, directive, value); - if (error != 0) { - close(fd); - return (error); - } - continue; - } - - /* Loop through the array looking for a match for the value */ - for (n = 0; options[n].directive != NULL; n++) { - error = fnmatch(options[n].directive, directive, - FNM_NOESCAPE); - if (error == 0) { - found = 1; - /* Call function for array index item */ - if (options[n].action != NULL) { - error = options[n].action( - &options[n], - line, directive, value); - if (error != 0) { - close(fd); - return (error); - } - } - } else if (error != FNM_NOMATCH) { - /* An error has occurred */ - close(fd); - return (-1); - } - } - if (!found && unknown != NULL) { - /* - * No match was found for the value we read from the - * file; call function designated for unknown values. - */ - error = unknown(NULL, line, directive, value); - if (error != 0) { - close(fd); - return (error); - } - } - } - - close(fd); - return (0); -} diff --git a/lib/libfigpar/figpar.h b/lib/libfigpar/figpar.h deleted file mode 100644 index 16f825a88..000000000 --- a/lib/libfigpar/figpar.h +++ /dev/null @@ -1,99 +0,0 @@ -/*- - * Copyright (c) 2002-2014 Devin Teske - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * $FreeBSD$ - */ - -#ifndef _FIGPAR_H_ -#define _FIGPAR_H_ - -#include - -/* - * Union for storing various types of data in a single common container. - */ -union fp_cfgvalue { - void *data; /* Pointer to NUL-terminated string */ - char *str; /* Pointer to NUL-terminated string */ - char **strarray; /* Pointer to an array of strings */ - int32_t num; /* Signed 32-bit integer value */ - uint32_t u_num; /* Unsigned 32-bit integer value */ - uint32_t boolean:1; /* Boolean integer value (0 or 1) */ -}; - -/* - * Option types (based on above cfgvalue union) - */ -enum fp_cfgtype { - FP_TYPE_NONE = 0x0000, /* for directives with no value */ - FP_TYPE_BOOL = 0x0001, /* boolean */ - FP_TYPE_INT = 0x0002, /* signed 32 bit integer */ - FP_TYPE_UINT = 0x0004, /* unsigned 32 bit integer */ - FP_TYPE_STR = 0x0008, /* string pointer */ - FP_TYPE_STRARRAY = 0x0010, /* string array pointer */ - FP_TYPE_DATA1 = 0x0020, /* void data type-1 (whatever) */ - FP_TYPE_DATA2 = 0x0040, /* void data type-2 (whatever) */ - FP_TYPE_DATA3 = 0x0080, /* void data type-3 (whatever) */ - FP_TYPE_RESERVED1 = 0x0100, /* reserved data type-1 (future) */ - FP_TYPE_RESERVED2 = 0x0200, /* reserved data type-2 (future) */ - FP_TYPE_RESERVED3 = 0x0400, /* reserved data type-3 (future) */ -}; - -/* - * Options to parse_config() for processing_options bitmask - */ -#define FP_BREAK_ON_EQUALS 0x0001 /* stop reading directive at `=' */ -#define FP_BREAK_ON_SEMICOLON 0x0002 /* `;' starts a new line */ -#define FP_CASE_SENSITIVE 0x0004 /* directives are case sensitive */ -#define FP_REQUIRE_EQUALS 0x0008 /* assignment directives only */ -#define FP_STRICT_EQUALS 0x0010 /* `=' must be part of directive */ - -/* - * Anatomy of a config file option - */ -struct fp_config { - enum fp_cfgtype type; /* Option value type */ - const char *directive; /* config file keyword */ - union fp_cfgvalue value; /* NB: set by action */ - - /* - * Function pointer; action to be taken when the directive is found - */ - int (*action)(struct fp_config *option, uint32_t line, char *directive, - char *value); -}; -extern struct fp_config fp_dummy_config; - -__BEGIN_DECLS -int parse_config(struct fp_config _options[], - const char *_path, - int (*_unknown)(struct fp_config *_option, - uint32_t _line, char *_directive, char *_value), - uint16_t _processing_options); -struct fp_config *get_config_option(struct fp_config _options[], - const char *_directive); -__END_DECLS - -#endif /* _FIGPAR_H_ */ diff --git a/lib/libfigpar/string_m.c b/lib/libfigpar/string_m.c deleted file mode 100644 index d358e9048..000000000 --- a/lib/libfigpar/string_m.c +++ /dev/null @@ -1,309 +0,0 @@ -/*- - * Copyright (c) 2001-2014 Devin Teske - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - */ - -#include -__FBSDID("$FreeBSD$"); - -#include - -#include -#include -#include -#include -#include - -#include "string_m.h" - -/* - * Counts the number of occurrences of one string that appear in the source - * string. Return value is the total count. - * - * An example use would be if you need to know how large a block of memory - * needs to be for a replaceall() series. - */ -unsigned int -strcount(const char *source, const char *find) -{ - const char *p = source; - size_t flen; - unsigned int n = 0; - - /* Both parameters are required */ - if (source == NULL || find == NULL) - return (0); - - /* Cache the length of find element */ - flen = strlen(find); - if (strlen(source) == 0 || flen == 0) - return (0); - - /* Loop until the end of the string */ - while (*p != '\0') { - if (strncmp(p, find, flen) == 0) { /* found an instance */ - p += flen; - n++; - } else - p++; - } - - return (n); -} - -/* - * Replaces all occurrences of `find' in `source' with `replace'. - * - * You should not pass a string constant as the first parameter, it needs to be - * a pointer to an allocated block of memory. The block of memory that source - * points to should be large enough to hold the result. If the length of the - * replacement string is greater than the length of the find string, the result - * will be larger than the original source string. To allocate enough space for - * the result, use the function strcount() declared above to determine the - * number of occurrences and how much larger the block size needs to be. - * - * If source is not large enough, the application will crash. The return value - * is the length (in bytes) of the result. - * - * When an error occurs, -1 is returned and the global variable errno is set - * accordingly. Returns zero on success. - */ -int -replaceall(char *source, const char *find, const char *replace) -{ - char *p; - char *t; - char *temp; - size_t flen; - size_t rlen; - size_t slen; - uint32_t n = 0; - - errno = 0; /* reset global error number */ - - /* Check that we have non-null parameters */ - if (source == NULL) - return (0); - if (find == NULL) - return (strlen(source)); - - /* Cache the length of the strings */ - slen = strlen(source); - flen = strlen(find); - rlen = replace ? strlen(replace) : 0; - - /* Cases where no replacements need to be made */ - if (slen == 0 || flen == 0 || slen < flen) - return (slen); - - /* If replace is longer than find, we'll need to create a temp copy */ - if (rlen > flen) { - temp = malloc(slen + 1); - if (errno != 0) /* could not allocate memory */ - return (-1); - strcpy(temp, source); - } else - temp = source; - - /* Reconstruct the string with the replacements */ - p = source; t = temp; /* position elements */ - - while (*t != '\0') { - if (strncmp(t, find, flen) == 0) { - /* found an occurrence */ - for (n = 0; replace && replace[n]; n++) - *p++ = replace[n]; - t += flen; - } else - *p++ = *t++; /* copy character and increment */ - } - - /* Terminate the string */ - *p = '\0'; - - /* Free the temporary allocated memory */ - if (temp != source) - free(temp); - - /* Return the length of the completed string */ - return (strlen(source)); -} - -/* - * Expands escape sequences in a buffer pointed to by `source'. This function - * steps through each character, and converts escape sequences such as "\n", - * "\r", "\t" and others into their respective meanings. - * - * You should not pass a string constant or literal to this function or the - * program will likely segmentation fault when it tries to modify the data. - * - * The string length will either shorten or stay the same depending on whether - * any escape sequences were converted but the amount of memory allocated does - * not change. - * - * Interpreted sequences are: - * - * \0NNN character with octal value NNN (0 to 3 digits) - * \N character with octal value N (0 thru 7) - * \a alert (BEL) - * \b backslash - * \f form feed - * \n new line - * \r carriage return - * \t horizontal tab - * \v vertical tab - * \xNN byte with hexadecimal value NN (1 to 2 digits) - * - * All other sequences are unescaped (ie. '\"' and '\#'). - */ -void strexpand(char *source) -{ - uint8_t c; - char *chr; - char *pos; - char d[4]; - - /* Initialize position elements */ - pos = chr = source; - - /* Loop until we hit the end of the string */ - while (*pos != '\0') { - if (*chr != '\\') { - *pos = *chr; /* copy character to current offset */ - pos++; - chr++; - continue; - } - - /* Replace the backslash with the correct character */ - switch (*++chr) { - case 'a': *pos = '\a'; break; /* bell/alert (BEL) */ - case 'b': *pos = '\b'; break; /* backspace */ - case 'f': *pos = '\f'; break; /* form feed */ - case 'n': *pos = '\n'; break; /* new line */ - case 'r': *pos = '\r'; break; /* carriage return */ - case 't': *pos = '\t'; break; /* horizontal tab */ - case 'v': *pos = '\v'; break; /* vertical tab */ - case 'x': /* hex value (1 to 2 digits)(\xNN) */ - d[2] = '\0'; /* pre-terminate the string */ - - /* verify next two characters are hex */ - d[0] = isxdigit(*(chr+1)) ? *++chr : '\0'; - if (d[0] != '\0') - d[1] = isxdigit(*(chr+1)) ? *++chr : '\0'; - - /* convert the characters to decimal */ - c = (uint8_t)strtoul(d, 0, 16); - - /* assign the converted value */ - *pos = (c != 0 || d[0] == '0') ? c : *++chr; - break; - case '0': /* octal value (0 to 3 digits)(\0NNN) */ - d[3] = '\0'; /* pre-terminate the string */ - - /* verify next three characters are octal */ - d[0] = (isdigit(*(chr+1)) && *(chr+1) < '8') ? - *++chr : '\0'; - if (d[0] != '\0') - d[1] = (isdigit(*(chr+1)) && *(chr+1) < '8') ? - *++chr : '\0'; - if (d[1] != '\0') - d[2] = (isdigit(*(chr+1)) && *(chr+1) < '8') ? - *++chr : '\0'; - - /* convert the characters to decimal */ - c = (uint8_t)strtoul(d, 0, 8); - - /* assign the converted value */ - *pos = c; - break; - default: /* single octal (\0..7) or unknown sequence */ - if (isdigit(*chr) && *chr < '8') { - d[0] = *chr; - d[1] = '\0'; - *pos = (uint8_t)strtoul(d, 0, 8); - } else - *pos = *chr; - } - - /* Increment to next offset, possible next escape sequence */ - pos++; - chr++; - } -} - -/* - * Expand only the escaped newlines in a buffer pointed to by `source'. This - * function steps through each character, and converts the "\n" sequence into - * a literal newline and the "\\n" sequence into "\n". - * - * You should not pass a string constant or literal to this function or the - * program will likely segmentation fault when it tries to modify the data. - * - * The string length will either shorten or stay the same depending on whether - * any escaped newlines were converted but the amount of memory allocated does - * not change. - */ -void strexpandnl(char *source) -{ - uint8_t backslash = 0; - char *cp1; - char *cp2; - - /* Replace '\n' with literal in dprompt */ - cp1 = cp2 = source; - while (*cp2 != '\0') { - *cp1 = *cp2; - if (*cp2 == '\\') - backslash++; - else if (*cp2 != 'n') - backslash = 0; - else if (backslash > 0) { - *(--cp1) = (backslash & 1) == 1 ? '\n' : 'n'; - backslash = 0; - } - cp1++; - cp2++; - } - *cp1 = *cp2; -} - -/* - * Convert a string to lower case. You should not pass a string constant to - * this function. Only pass pointers to allocated memory with null terminated - * string data. - */ -void -strtolower(char *source) -{ - char *p = source; - - if (source == NULL) - return; - - while (*p != '\0') { - *p = tolower(*p); - p++; /* would have just used `*p++' but gcc 3.x warns */ - } -} diff --git a/lib/libfigpar/string_m.h b/lib/libfigpar/string_m.h deleted file mode 100644 index 18a3fccb2..000000000 --- a/lib/libfigpar/string_m.h +++ /dev/null @@ -1,43 +0,0 @@ -/*- - * Copyright (c) 2001-2014 Devin Teske - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * $FreeBSD$ - */ - -#ifndef _STRING_M_H_ -#define _STRING_M_H_ - -#include - -__BEGIN_DECLS -void strexpand(char *_source); -void strexpandnl(char *_source); -void strtolower(char *_source); -int replaceall(char *_source, const char *_find, - const char *_replace); -unsigned int strcount(const char *_source, const char *_find); -__END_DECLS - -#endif /* !_STRING_M_H_ */ diff --git a/share/mk/bsd.libnames.mk b/share/mk/bsd.libnames.mk index f8de3f4ff..fcae1688f 100644 --- a/share/mk/bsd.libnames.mk +++ b/share/mk/bsd.libnames.mk @@ -45,13 +45,11 @@ LIBDEVSTAT?= ${DESTDIR}${LIBDIR}/libdevstat.a LIBDIALOG?= ${DESTDIR}${LIBDIR}/libdialog.a LIBDISK?= ${DESTDIR}${LIBDIR}/libdisk.a LIBDNS?= ${DESTDIR}${LIBDIR}/libdns.a -LIBDPV?= ${DESTDIR}${LIBDIR}/libdpv.a LIBDTRACE?= ${DESTDIR}${LIBDIR}/libdtrace.a LIBDWARF?= ${DESTDIR}${LIBDIR}/libdwarf.a LIBEDIT?= ${DESTDIR}${LIBDIR}/libedit.a LIBELF?= ${DESTDIR}${LIBDIR}/libelf.a LIBFETCH?= ${DESTDIR}${LIBDIR}/libfetch.a -LIBFIGPAR?= ${DESTDIR}${LIBDIR}/libfigpar.a LIBFL?= "don't use LIBFL, use LIBL" LIBFORM?= ${DESTDIR}${LIBDIR}/libform.a LIBFTPIO?= ${DESTDIR}${LIBDIR}/libftpio.a diff --git a/sys/sys/param.h b/sys/sys/param.h index 2a6d1778f..5adcdad57 100644 --- a/sys/sys/param.h +++ b/sys/sys/param.h @@ -58,7 +58,7 @@ * in the range 5 to 9. */ #undef __FreeBSD_version -#define __FreeBSD_version 903507 /* Master, propagated to newvers */ +#define __FreeBSD_version 903506 /* Master, propagated to newvers */ /* * __FreeBSD_kernel__ indicates that this system uses the kernel of FreeBSD, diff --git a/usr.bin/Makefile b/usr.bin/Makefile index ecc64dadd..93c92967b 100644 --- a/usr.bin/Makefile +++ b/usr.bin/Makefile @@ -36,7 +36,6 @@ SUBDIR= alias \ ctlstat \ cut \ dirname \ - dpv \ du \ ee \ elf2aout \ diff --git a/usr.bin/dpv/Makefile b/usr.bin/dpv/Makefile deleted file mode 100644 index 6f89c0fbb..000000000 --- a/usr.bin/dpv/Makefile +++ /dev/null @@ -1,12 +0,0 @@ -# $FreeBSD$ - -PROG= dpv - -CFLAGS+= -I${.CURDIR} - -DPADD= ${LIBDPV} ${LIBDIALOG} ${LIBFIGPAR} ${LIBNCURSESW} ${LIBUTIL} ${LIBM} -LDADD= -ldpv -ldialog -lfigpar -lncursesw -lutil -lm - -WARNS?= 6 - -.include diff --git a/usr.bin/dpv/dpv.1 b/usr.bin/dpv/dpv.1 deleted file mode 100644 index c8d321bea..000000000 --- a/usr.bin/dpv/dpv.1 +++ /dev/null @@ -1,430 +0,0 @@ -.\" Copyright (c) 2013-2014 Devin Teske -.\" All rights reserved. -.\" -.\" Redistribution and use in source and binary forms, with or without -.\" modification, are permitted provided that the following conditions -.\" are met: -.\" 1. Redistributions of source code must retain the above copyright -.\" notice, this list of conditions and the following disclaimer. -.\" 2. Redistributions in binary form must reproduce the above copyright -.\" notice, this list of conditions and the following disclaimer in the -.\" documentation and/or other materials provided with the distribution. -.\" -.\" THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND -.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE -.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE -.\" ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE -.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL -.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS -.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) -.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT -.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY -.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF -.\" SUCH DAMAGE. -.\" -.\" $FreeBSD$ -.\" -.Dd Sep 7, 2014 -.Dt DPV 1 -.Os -.Sh NAME -.Nm dpv -.Nd stream data from stdin or multiple paths with dialog progress view -.Sh SYNOPSIS -.Nm -.Op options -.Ar [bytes:]label -.Nm -.Op options -.Fl m -.Ar [bytes1:]label1 -.Ar path1 -.Op Ar [bytes2:]label2 path2 ... -.Sh DESCRIPTION -.Nm -provides a dialog progress view, allowing a user to see current throughput rate -and total data transferred for one or more streams. -.Pp -The -.Nm -utility has two main modes for processing input. -.Pp -The default input mode, without -.Ql Fl m , -.Nm -reads bytes from standard input. -A label for the data must be provided. -.Pp -The secondary input mode, with -.Ql Fl m , -.Nm -reads multiple paths -.Pq up to 2047 or Dq ARG_MAX/2-1 , -sequentially. -.Pp -Data read in either mode is either thrown away -.Pq default , -sent to a spawned instance of the program specified via -.Ql Fl x Ar cmd , -or sent to a unique file specified by -.Ql Fl o Ar file . -.Pp -With or without -.Ql Fl m , -progress is displayed using one of -.Xr dialog 3 -.Pq default , -.Xr dialog 1 -.Pq see Ql Fl D , -or instead -.Xr Xdialog 1 -.Pq see Ql Fl X . -.Pp -The following options are available: -.Bl -tag -width ".Fl b Ar backtitle" -.It Fl a Ar text -Display -.Ar text -below the file progress indicator(s). -.It Fl b Ar backtitle -Display -.Ar backtitle -on the backdrop, at top-left, behind the dialog widget. -When using -.Xr Xdialog 1 , -this is displayed inside the window -.Pq at the top -followed by a separator line. -.It Fl d -Debug mode. -Print dialog prompt data to standard out and provide additional debugging on -standard error. -.It Fl D -Do not use the default interface of -.Xr dialog 3 , -but instead spawn an instance of -.Xr dialog 1 . -The path to -.Xr dialog 1 -is taken from the -.Ev DIALOG -environment variable or simply -.Dq Li dialog -if unset or NULL. -.It Fl h -Produce a short syntax usage with brief option descriptions and exit. -Output is produced on standard error. -.It Fl i Ar format -Customize the single-file format string used to update the status line. -Ignored when using either -.Ql Fl D -or -.Ql Fl X -which lack the ability to display the status line -.Pq containing bytes/rate/thread information . -Default value -is -.Dq Li %'10lli bytes read @ %'9.1f bytes/sec. . -This format is used when handling one file. -.It Fl I Ar format -Customize the multi-file format string used to update the status line. -Ignored when using either -.Ql Fl D -or -.Ql Fl X -which lack the ability to display the status line -.Pq containing bytes/rate/thread information . -Default value -is -.Dq Li %'10lli bytes read @ %'9.1f bytes/sec. [%i/%i busy/wait] . -This format is used when handling more than one file. -.It Fl l -Line mode. Read lines from input instead of bytes. -.It Fl L Ar size -Label size. -If negative, shrink to longest label width. -.It Fl m -Multi-input mode. -Instead of reading bytes from standard input, read from a set of paths -.Pq one for each label . -By default, each path is processed sequentially in the order given. -.It Fl n Ar num -Display at-most -.Ar num -progress indicators per screen. -If zero, display as many as possible. -If negative, only display the main progress indicator. -Default is 0. -Maximum value is 10. -.It Fl N -No overrun. -If enabled, stop reading known-length inputs when input reaches stated length. -.It Fl o Ar file -Output data to -.Ar file . -The first occurrence of -.Ql %s -.Pq if any -in -.Ql Ar file -will be replaced with the -.Ar label -text. -.It Fl p Ar text -Display -.Ar text -above the file progress indicator(s). -.It Fl P Ar size -Mini-progressbar size. -If negative, don't display mini-progressbars -.Pq only the large overall progress indicator is shown . -If zero, auto-adjust based on number of files to read. -When zero and only one file to read, defaults to -1. -When zero and more than one file to read, defaults to 17. -.It Fl t Ar title -Display -.Ar title -atop the dialog box. -Note that if you use this option at the same time as -.Ql Fl X -and -.Ql Fl b Ar backtitle , -the -.Ar backtitle -and -.Ar title -are effectively switched -.Pq see BUGS section below . -.It Fl T -Test mode. -Simulate reading a number of bytes, divided evenly across the number of files, -while stepping through each percent value of each file to process. -Appends -.Dq Li [TEST MODE] -to the status line -.Pq to override, use Ql Fl u Ar format . -No data is actually read. -.It Fl U Ar num -Update status line -.Ar num -times per-second. -Default value is -.Ql Li 2 . -A value of -.Ql Li 0 -disables status line updates. -If negative, update the status line as fast as possible. -Ignored when using either -.Ql Fl D -or -.Ql Fl X -which lack the ability to display the status line -.Pq containing bytes/rate/thread information . -.It Fl w -Wide mode. -Allows long -.Ar text -arguments used with -.Ql Fl p -and -.Ql Fl a -to bump the dialog width. -Prompts wider than the maximum width will wrap -.Pq unless using Xr Xdialog 1 ; see BUGS section below . -.It Fl x Ar cmd -Execute -.Ar cmd -.Pq via Xr sh 1 -and send it data that has been read. -Data is available to -.Ar cmd -on standard input. -With -.Ql Fl m , -.Ar cmd -is executed once for each -.Ar path -argument. -The first occurrence of -.Ql %s -.Pq if any -in -.Ql Ar cmd -will be replaced with the -.Ar label -text. -.It Fl X -Enable X11 mode by using -.Xr Xdialog 1 -instead of -.Xr dialog 1 -or -.Xr dialog 3 . -.El -.Sh ENVIRONMENT -The following environment variables are referenced by -.Nm : -.Bl -tag -width ".Ev USE_COLOR" -.It Ev DIALOG -Override command string used to launch -.Xr dialog 1 -.Pq requires Ql Fl D -or -.Xr Xdialog 1 -.Pq requires Ql Fl X ; -default is either -.Ql dialog -.Pq for Ql Fl D -or -.Ql Xdialog -.Pq for Ql Fl X . -.It Ev DIALOGRC -If set and non-NULL, path to -.Ql .dialogrc -file. -.It Ev HOME -If -.Ql Ev $DIALOGRC -is either not set or NULL, used as a prefix to -.Ql .dialogrc -.Pq i.e., Ql $HOME/.dialogrc . -.It Ev USE_COLOR -If set and NULL, disables the use of color when using -.Xr dialog 1 -.Pq does not apply to Xr Xdialog 1 . -.El -.Sh DEPENDENCIES -If using -.Ql Fl D , -.Xr dialog 1 -is required. -.Pp -If using -.Ql Fl X , -.Xr Xdialog 1 -is required. -.Sh FILES -.Bl -tag -width ".Pa $HOME/.dialogrc" -compact -.It Pa $HOME/.dialogrc -.El -.Sh EXAMPLES -.Pp -Simple example to show how fast -.Xr yes 1 -produces lines -.Pq usually about ten-million per-second; your results may vary : -.Bd -literal -offset indent -yes | dpv -l yes -.Ed -.Pp -Display progress while timing how long it takes -.Xr yes 1 -to produce a half-billion lines -.Pq usually under one minute; your results may vary : -.Bd -literal -offset indent -time yes | dpv -Nl 500000000:yes -.Ed -.Pp -An example to watch how quickly a file is transferred using -.Xr nc 1 : -.Bd -literal -offset indent -dpv -x "nc -w 1 somewhere.com 3000" -m label file -.Ed -.Pp -A similar example, transferring a file from another process and passing the -expected size to -.Nm : -.Bd -literal -offset indent -cat file | dpv -x "nc -w 1 somewhere.com 3000" 12345:label -.Ed -.Pp -A more complicated example: -.Bd -literal -offset indent -tar cf - . | dpv -x "gzip -9 > out.tgz" \\ - $( du -s . | awk '{print $1 * 1024}' ):label -.Ed -.Pp -Taking an image of a disk: -.Bd -literal -offset indent -dpv -o disk-image.img -m label /dev/ada0 -.Ed -.Pp -Writing an image back to a disk: -.Bd -literal -offset indent -dpv -o /dev/ada0 -m label disk-image.img -.Ed -.Pp -Zeroing a disk: -.Bd -literal -offset indent -dpv -o /dev/md42 < /dev/zero -.Ed -.Pp -.Sh BUGS -.Xr Xdialog 1 , -when given both -.Ql Fl -title Ar title -.Pq see above Ql Fl t Ar title -and -.Ql Fl -backtitle Ar backtitle -.Pq see above Ql Fl b Ar backtitle , -displays the backtitle in place of the title and vice-versa. -.Pp -.Xr Xdialog 1 -does not wrap long prompt texts received after initial launch. -This is a known issue with the -.Ql --gauge -widget in -.Xr Xdialog 1 . -.Pp -.Xr dialog 1 -does not display the first character after a series of escaped escape-sequences -(e.g., ``\\\\n'' produces ``\\'' instead of ``\\n''). -This is a known issue with -.Xr dialog 1 -and does not affect -.Xr dialog 3 -or -.Xr Xdialog 1 . -.Pp -If your application ignores -.Ev USE_COLOR -when set and NULL before calling -.Xr dpv 1 -with color escape sequences anyway, -.Xr dialog 3 -and -.Xr dialog 1 -may not render properly. -Workaround is to detect when -.Ev USE_COLOR -is set and NULL and either not use color escape sequences at that time or use -.Xr unset 1 -.Xr [ sh 1 ] -or -.Xr unsetenv 1 -.Xr [ csh 1 ] -to unset -.Ev USE_COLOR , -forcing interpretation of color sequences. -This does not effect -.Xr Xdialog 1 , -which renders the color escape sequences as plain text. -See -.Do Li -embedded "\\Z" sequences -.Dc -in -.Xr dialog 1 -for additional information. -.Sh SEE ALSO -.Xr dialog 1 , -.Xr dialog 3 , -.Xr sh 1 , -.Xr Xdialog 1 -.Sh HISTORY -A -.Nm -utility first appeared in -.Fx 11.0 . -.Sh AUTHORS -.An Devin Teske Aq dteske@FreeBSD.org diff --git a/usr.bin/dpv/dpv.c b/usr.bin/dpv/dpv.c deleted file mode 100644 index 4e006f6c1..000000000 --- a/usr.bin/dpv/dpv.c +++ /dev/null @@ -1,541 +0,0 @@ -/*- - * Copyright (c) 2013-2014 Devin Teske - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - */ - -#include -__FBSDID("$FreeBSD$"); - -#include -#include - -#define _BSD_SOURCE /* to get dprintf() prototype in stdio.h below */ -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include "dpv_util.h" - -/* Debugging */ -static uint8_t debug = FALSE; - -/* Data to process */ -static struct dpv_file_node *file_list = NULL; -static unsigned int nfiles = 0; - -/* Data processing */ -static uint8_t line_mode = FALSE; -static uint8_t no_overrun = FALSE; -static char *buf = NULL; -static int fd = -1; -static int output_type = DPV_OUTPUT_NONE; -static size_t bsize; -static char rpath[PATH_MAX]; - -/* Extra display information */ -static uint8_t multiple = FALSE; /* `-m' */ -static char *pgm; /* set to argv[0] by main() */ - -/* Function prototypes */ -static void sig_int(int sig); -static void usage(void); -int main(int argc, char *argv[]); -static int operate_common(struct dpv_file_node *file, int out); -static int operate_on_bytes(struct dpv_file_node *file, int out); -static int operate_on_lines(struct dpv_file_node *file, int out); - -static int -operate_common(struct dpv_file_node *file, int out) -{ - struct stat sb; - - /* Open the file if necessary */ - if (fd < 0) { - if (multiple) { - /* Resolve the file path and attempt to open it */ - if (realpath(file->path, rpath) == 0 || - (fd = open(rpath, O_RDONLY)) < 0) { - warn("%s", file->path); - file->status = DPV_STATUS_FAILED; - return (-1); - } - } else { - /* Assume stdin, but if that's a TTY instead use the - * highest numbered file descriptor (obtained by - * generating new fd and then decrementing). - * - * NB: /dev/stdin should always be open(2)'able - */ - fd = STDIN_FILENO; - if (isatty(fd)) { - fd = open("/dev/stdin", O_RDONLY); - close(fd--); - } - - /* This answer might be wrong, if dpv(3) has (by - * request) opened an output file or pipe. If we - * told dpv(3) to open a file, subtract one from - * previous answer. If instead we told dpv(3) to - * prepare a pipe output, subtract two. - */ - switch(output_type) { - case DPV_OUTPUT_FILE: - fd -= 1; - break; - case DPV_OUTPUT_SHELL: - fd -= 2; - break; - } - } - } - - /* Allocate buffer if necessary */ - if (buf == NULL) { - /* Use output block size as buffer size if available */ - if (out >= 0) { - if (fstat(out, &sb) != 0) { - warn("%i", out); - file->status = DPV_STATUS_FAILED; - return (-1); - } - if (S_ISREG(sb.st_mode)) { - if (sysconf(_SC_PHYS_PAGES) > - PHYSPAGES_THRESHOLD) - bsize = MIN(BUFSIZE_MAX, MAXPHYS * 8); - else - bsize = BUFSIZE_SMALL; - } else - bsize = MAX(sb.st_blksize, - (blksize_t)sysconf(_SC_PAGESIZE)); - } else - bsize = MIN(BUFSIZE_MAX, MAXPHYS * 8); - - /* Attempt to allocate */ - if ((buf = malloc(bsize+1)) == NULL) { - end_dialog(); - err(EXIT_FAILURE, "Out of memory?!"); - } - } - - return (0); -} - -static int -operate_on_bytes(struct dpv_file_node *file, int out) -{ - int progress; - ssize_t r, w; - - if (operate_common(file, out) < 0) - return (-1); - - /* [Re-]Fill the buffer */ - if ((r = read(fd, buf, bsize)) <= 0) { - if (fd != STDIN_FILENO) - close(fd); - fd = -1; - file->status = DPV_STATUS_DONE; - return (100); - } - - /* [Re-]Dump the buffer */ - if (out >= 0) { - if ((w = write(out, buf, r)) < 0) { - end_dialog(); - err(EXIT_FAILURE, "output"); - } - fsync(out); - } - - dpv_overall_read += r; - file->read += r; - - /* Calculate percentage of completion (if possible) */ - if (file->length >= 0) { - progress = (file->read * 100 / (file->length > 0 ? - file->length : 1)); - - /* If no_overrun, do not return 100% until read >= length */ - if (no_overrun && progress == 100 && file->read < file->length) - progress--; - - return (progress); - } else - return (-1); -} - -static int -operate_on_lines(struct dpv_file_node *file, int out) -{ - char *p; - int progress; - ssize_t r, w; - - if (operate_common(file, out) < 0) - return (-1); - - /* [Re-]Fill the buffer */ - if ((r = read(fd, buf, bsize)) <= 0) { - if (fd != STDIN_FILENO) - close(fd); - fd = -1; - file->status = DPV_STATUS_DONE; - return (100); - } - buf[r] = '\0'; - - /* [Re-]Dump the buffer */ - if (out >= 0) { - if ((w = write(out, buf, r)) < 0) { - end_dialog(); - err(EXIT_FAILURE, "output"); - } - fsync(out); - } - - /* Process the buffer for number of lines */ - for (p = buf; p != NULL && *p != '\0';) - if ((p = strchr(p, '\n')) != NULL) - dpv_overall_read++, p++, file->read++; - - /* Calculate percentage of completion (if possible) */ - if (file->length >= 0) { - progress = (file->read * 100 / file->length); - - /* If no_overrun, do not return 100% until read >= length */ - if (no_overrun && progress == 100 && file->read < file->length) - progress--; - - return (progress); - } else - return (-1); -} - -/* - * Takes a list of names that are to correspond to input streams coming from - * stdin or fifos and produces necessary config to drive dpv(3) `--gauge' - * widget. If the `-d' flag is used, output is instead send to terminal - * standard output (and the output can then be saved to a file, piped into - * custom [X]dialog(1) invocation, or whatever. - */ -int -main(int argc, char *argv[]) -{ - char dummy; - int ch; - int n = 0; - size_t config_size = sizeof(struct dpv_config); - size_t file_node_size = sizeof(struct dpv_file_node); - struct dpv_config *config; - struct dpv_file_node *curfile; - struct sigaction act; - - pgm = argv[0]; /* store a copy of invocation name */ - - /* Allocate config structure */ - if ((config = malloc(config_size)) == NULL) - errx(EXIT_FAILURE, "Out of memory?!"); - memset((void *)(config), '\0', config_size); - - /* - * Process command-line options - */ - while ((ch = getopt(argc, argv, - "a:b:dDhi:I:lL:mn:No:p:P:t:TU:wx:X")) != -1) { - switch(ch) { - case 'a': /* additional message text to append */ - if (config->aprompt == NULL) { - config->aprompt = malloc(DPV_APROMPT_MAX); - if (config->aprompt == NULL) - errx(EXIT_FAILURE, "Out of memory?!"); - } - snprintf(config->aprompt, DPV_APROMPT_MAX, "%s", - optarg); - break; - case 'b': /* [X]dialog(1) backtitle */ - if (config->backtitle != NULL) - free((char *)config->backtitle); - config->backtitle = malloc(strlen(optarg) + 1); - if (config->backtitle == NULL) - errx(EXIT_FAILURE, "Out of memory?!"); - *(config->backtitle) = '\0'; - strcat(config->backtitle, optarg); - break; - case 'd': /* debugging */ - debug = TRUE; - config->debug = debug; - break; - case 'D': /* use dialog(1) instead of libdialog */ - config->display_type = DPV_DISPLAY_DIALOG; - break; - case 'h': /* help/usage */ - usage(); - break; /* NOTREACHED */ - case 'i': /* status line format string for single-file */ - config->status_solo = optarg; - break; - case 'I': /* status line format string for many-files */ - config->status_many = optarg; - break; - case 'l': /* Line mode */ - line_mode = TRUE; - break; - case 'L': /* custom label size */ - config->label_size = - (int)strtol(optarg, (char **)NULL, 10); - if (config->label_size == 0 && errno == EINVAL) - errx(EXIT_FAILURE, - "`-L' argument must be numeric"); - else if (config->label_size < -1) - config->label_size = -1; - break; - case 'm': /* enable multiple file arguments */ - multiple = TRUE; - break; - case 'o': /* `-o path' for sending data-read to file */ - output_type = DPV_OUTPUT_FILE; - config->output_type = DPV_OUTPUT_FILE; - config->output = optarg; - break; - case 'n': /* custom number of files per `page' */ - config->display_limit = - (int)strtol(optarg, (char **)NULL, 10); - if (config->display_limit == 0 && errno == EINVAL) - errx(EXIT_FAILURE, - "`-n' argument must be numeric"); - else if (config->display_limit < 0) - config->display_limit = -1; - break; - case 'N': /* No overrun (truncate reads of known-length) */ - no_overrun = TRUE; - config->options |= DPV_NO_OVERRUN; - break; - case 'p': /* additional message text to use as prefix */ - if (config->pprompt == NULL) { - config->pprompt = malloc(DPV_PPROMPT_MAX + 2); - if (config->pprompt == NULL) - errx(EXIT_FAILURE, "Out of memory?!"); - /* +2 is for implicit "\n" appended later */ - } - snprintf(config->pprompt, DPV_PPROMPT_MAX, "%s", - optarg); - break; - case 'P': /* custom size for mini-progressbar */ - config->pbar_size = - (int)strtol(optarg, (char **)NULL, 10); - if (config->pbar_size == 0 && errno == EINVAL) - errx(EXIT_FAILURE, - "`-P' argument must be numeric"); - else if (config->pbar_size < -1) - config->pbar_size = -1; - break; - case 't': /* [X]dialog(1) title */ - if (config->title != NULL) - free(config->title); - config->title = malloc(strlen(optarg) + 1); - if (config->title == NULL) - errx(EXIT_FAILURE, "Out of memory?!"); - *(config->title) = '\0'; - strcat(config->title, optarg); - break; - case 'T': /* test mode (don't read data, fake it) */ - config->options |= DPV_TEST_MODE; - break; - case 'U': /* updates per second */ - config->status_updates_per_second = - (int)strtol(optarg, (char **)NULL, 10); - if (config->status_updates_per_second == 0 && - errno == EINVAL) - errx(EXIT_FAILURE, - "`-U' argument must be numeric"); - break; - case 'w': /* `-p' and `-a' widths bump [X]dialog(1) width */ - config->options |= DPV_WIDE_MODE; - break; - case 'x': /* `-x cmd' for sending data-read to sh(1) code */ - output_type = DPV_OUTPUT_SHELL; - config->output_type = DPV_OUTPUT_SHELL; - config->output = optarg; - break; - case 'X': /* X11 support through x11/xdialog */ - config->display_type = DPV_DISPLAY_XDIALOG; - break; - case '?': /* unknown argument (based on optstring) */ - /* FALLTHROUGH */ - default: /* unhandled argument (based on switch) */ - usage(); - /* NOTREACHED */ - } - } - argc -= optind; - argv += optind; - - /* Process remaining arguments as list of names to display */ - for (curfile = file_list; n < argc; n++) { - nfiles++; - - /* Allocate a new struct for the file argument */ - if (curfile == NULL) { - if ((curfile = malloc(file_node_size)) == NULL) - errx(EXIT_FAILURE, "Out of memory?!"); - memset((void *)(curfile), '\0', file_node_size); - file_list = curfile; - } else { - if ((curfile->next = malloc(file_node_size)) == NULL) - errx(EXIT_FAILURE, "Out of memory?!"); - memset((void *)(curfile->next), '\0', file_node_size); - curfile = curfile->next; - } - curfile->name = argv[n]; - - /* Read possible `lines:' prefix from label syntax */ - if (sscanf(curfile->name, "%lli:%c", &(curfile->length), - &dummy) == 2) - curfile->name = strchr(curfile->name, ':') + 1; - else - curfile->length = -1; - - /* Read path argument if enabled */ - if (multiple) { - if (++n >= argc) - errx(EXIT_FAILURE, "Missing path argument " - "for label number %i", nfiles); - curfile->path = argv[n]; - } else - break; - } - - /* Display usage and exit if not given at least one name */ - if (nfiles == 0) { - warnx("no labels provided"); - usage(); - /* NOTREACHED */ - } - - /* - * Set cleanup routine for Ctrl-C action - */ - if (config->display_type == DPV_DISPLAY_LIBDIALOG) { - act.sa_handler = sig_int; - sigaction(SIGINT, &act, 0); - } - - /* Set status formats and action */ - if (line_mode) { - config->status_solo = LINE_STATUS_SOLO; - config->status_many = LINE_STATUS_SOLO; - config->action = operate_on_lines; - } else { - config->status_solo = BYTE_STATUS_SOLO; - config->status_many = BYTE_STATUS_SOLO; - config->action = operate_on_bytes; - } - - /* - * Hand off to dpv(3)... - */ - if (dpv(config, file_list) != 0 && debug) - warnx("dpv(3) returned error!?"); - - end_dialog(); - dpv_free(); - - exit(EXIT_SUCCESS); -} - -/* - * Interrupt handler to indicate we received a Ctrl-C interrupt. - */ -static void -sig_int(int sig __unused) -{ - dpv_interrupt = TRUE; -} - -/* - * Print short usage statement to stderr and exit with error status. - */ -static void -usage(void) -{ - - if (debug) /* No need for usage */ - exit(EXIT_FAILURE); - - fprintf(stderr, "Usage: %s [options] bytes:label\n", pgm); - fprintf(stderr, " %s [options] -m bytes1:label1 path1 " - "[bytes2:label2 path2 ...]\n", pgm); - fprintf(stderr, "OPTIONS:\n"); -#define OPTFMT "\t%-14s %s\n" - fprintf(stderr, OPTFMT, "-a text", - "Append text. Displayed below file progress indicators."); - fprintf(stderr, OPTFMT, "-b backtitle", - "String to be displayed on the backdrop, at top-left."); - fprintf(stderr, OPTFMT, "-d", - "Debug. Write to standard output instead of dialog."); - fprintf(stderr, OPTFMT, "-D", - "Use dialog(1) instead of dialog(3) [default]."); - fprintf(stderr, OPTFMT, "-h", - "Produce this output on standard error and exit."); - fprintf(stderr, OPTFMT, "-i format", - "Customize status line format. See fdpv(1) for details."); - fprintf(stderr, OPTFMT, "-I format", - "Customize status line format. See fdpv(1) for details."); - fprintf(stderr, OPTFMT, "-L size", - "Label size. Must be a number greater than 0, or -1."); - fprintf(stderr, OPTFMT, "-m", - "Enable processing of multiple file argiments."); - fprintf(stderr, OPTFMT, "-n num", - "Display at-most num files per screen. Default is -1."); - fprintf(stderr, OPTFMT, "-N", - "No overrun. Stop reading input at stated length, if any."); - fprintf(stderr, OPTFMT, "-o file", - "Output data to file. First %s replaced with label text."); - fprintf(stderr, OPTFMT, "-p text", - "Prefix text. Displayed above file progress indicators."); - fprintf(stderr, OPTFMT, "-P size", - "Mini-progressbar size. Must be a number greater than 3."); - fprintf(stderr, OPTFMT, "-t title", - "Title string to be displayed at top of dialog(1) box."); - fprintf(stderr, OPTFMT, "-T", - "Test mode. Don't actually read any data, but fake it."); - fprintf(stderr, OPTFMT, "-U num", - "Update status line num times per-second. Default is 2."); - fprintf(stderr, OPTFMT, "-w", - "Wide. Width of `-p' and `-a' text bump dialog(1) width."); - fprintf(stderr, OPTFMT, "-x cmd", - "Send data to executed cmd. First %s replaced with label."); - fprintf(stderr, OPTFMT, "-X", - "X11. Use Xdialog(1) instead of dialog(1)."); - exit(EXIT_FAILURE); -} diff --git a/usr.bin/dpv/dpv_util.h b/usr.bin/dpv/dpv_util.h deleted file mode 100644 index 36990be47..000000000 --- a/usr.bin/dpv/dpv_util.h +++ /dev/null @@ -1,68 +0,0 @@ -/*- - * Copyright (c) 2013-2014 Devin Teske - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * $FreeBSD$ - */ - -#ifndef _DPV_UTIL_H_ -#define _DPV_UTIL_H_ - -/* Limits */ -#define BUFSIZE_MAX (2 * 1024 * 1024) - /* Buffer size for read(2) input */ -#ifndef MAXPHYS -#define MAXPHYS (128 * 1024) - /* max raw I/O transfer size */ -#endif - -/* - * Memory strategry threshold, in pages: if physmem is larger than this, - * use a large buffer. - */ -#define PHYSPAGES_THRESHOLD (32 * 1024) - -/* - * Small (default) buffer size in bytes. It's inefficient for this to be - * smaller than MAXPHYS. - */ -#define BUFSIZE_SMALL (MAXPHYS) - -/* - * Math macros - */ -#undef MIN -#define MIN(x,y) ((x) < (y) ? (x) : (y)) -#undef MAX -#define MAX(x,y) ((x) > (y) ? (x) : (y)) - -/* - * Extra display information - */ -#define BYTE_STATUS_SOLO "%'10lli bytes read @ %'9.1f bytes/sec." -#define BYTE_STATUS_MANY (BYTE_STATUS_SOLO " [%i/%i busy/wait]") -#define LINE_STATUS_SOLO "%'10lli lines read @ %'9.1f lines/sec." -#define LINE_STATUS_MANY (LINE_STATUS_SOLO " [%i/%i busy/wait]") - -#endif /* !_DPV_UTIL_H_ */ -- 2.45.0